@ C++er各位 ideone.com/6ElBKy clang C++11 mode
— pepshiso (@pepshiso) May 5, 2013
clang のバグっぽいけど調査中
— pepshiso (@pepshiso) May 5, 2013
以下のコードがclangでコンパイルエラーになる。
template <class T>
void g()
{
T x(0);
}
template <class T>
void f()
{
struct local {
local(int) {}
};
g<local>();
}
int main()
{
f<void>();
}
エラーの内容は、g<local>で、適合するlocalのコンストラクターが見つからないというものだ。たしかにlocalにはint型をひとつ取るコンストラクターがあるというのに。
どうやらこれは、テンプレート(関数テンプレートやクラステンプレートのメンバー関数)内のローカルクラスを明示的テンプレート実引数指定すると、ローカルクラスのユーザー定義コンストラクターのlookupが失敗するというバグのようだ。
template < typename T >
struct S
{
T t ;
S() : t(0) { }
} ;
// local class defined inside template difinition.
template < typename T >
void f()
{
struct local { local( int ) { } } ;
S<local> s ;
}
// local class defined inside non-template difiniton.
void g()
{
struct local { local( int ) { } } ;
S<local> s ;
}
int main()
{
f<void>() ; // error: no matching constructor for initialization of 'local'
g() ; // OK, lookup works
}
テンプレート定義内で定義されていないローカルの場合は起こらない。
関数テンプレートの場合、明示的テンプレート実引数指定を使った場合だけ、この問題に引っかかる。
template < typename T >
void f( )
{
T x(0) ;
}
template < typename T >
void call_f_template()
{
struct local { local(int) {} } ;
f<local>() ;
}
void call_f()
{
struct local { local(int) {} } ;
f<local>() ;
}
int main()
{
call_f_template<void>() ; // error: no matching constructor for initialization of 'local'
call_f() ;
}
Argument Deductionが使える文脈ではエラーにならない。そのような文脈では、たとえexplicit template argument specificationを使ったとしても問題なく動く。
template < typename T >
void f( T const & )
{
T x(0) ;
}
template < typename T >
void call_f_template()
{
struct local { local(int) {} } ;
local obj(0) ;
f( obj ) ; // OK
f<local>( obj ) ; // Also OK
}
int main()
{
call_f_template<void>() ;
}
実に不思議なバグだ。はじめてclangのC++11フロントエンドのバグを目にした。
というわけでバグ報告してみた。
追記:すでに重複報告だった。しかも2011年から既知のバグだ。当時はコンパイラーがクラッシュするバグだったらしい。
Bug 9685 – Crash on using local struct in function template as template parameter
No comments:
Post a Comment
You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.