追記:これはgccのバグではなく、規格上の問題であった。
Dependant Nameは、Point of instantiationに解決される。つまり、
// point of difination of f template < typename T > void f(T x) { g(x) ; } // point of difination of g template < typename T > void g(T) { } int main() { // point of instantiation of f. // also g. f(0) ; }
このコードは、well-formedである。たしかに、fのpoint of difinationからは、gという名前は見えない。しかし、g(x)という式は、type-dependant expressionであるので、Dependant nameである。したがって、gのname lookupは、point of instantiationに行われる。すなわち、mainの中である。mainでは、gはすでに宣言されているので、問題なくgを使うことができる。
gccはVariadic Tempalteをサポートしていると聞いたので、以下のようなコードを書いてみた。
template < typename T, typename ... Args > T max( T const & a, T const & b, Args ... rest) { return max( max(a, b), rest ... ) ; } template < typename T > T max( T const & a, T const & b ) { return a < b ? b : a ; } int main() { max(1, 2, 3) ; }
ところが、gccは、このコードに対して、エラーを吐いた。しかし、どうもそのエラーメッセージがおかしい。試しに、以下のように書き換えてみたところ、
// 順番を逆にした template < typename T > T max( T const & a, T const & b ) { return a < b ? b : a ; } template < typename T, typename ... Args > T max( T const & a, T const & b, Args ... rest) { return max( max(a, b), rest ... ) ; }
これは、コンパイルが通った。明らかに、Variadic TemplateがらみのDependant Nameを、point of difinationで解決している。これは誤りである。
No comments:
Post a Comment