追記:これは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