これもまた「誰が上手いの?」のようです。gcc 6.0.0 と clang 3.7.0 の動作が異なるため、質問です。
const char *
非テンプレート引数として取り、特定のポインターに特化した変数テンプレートがあるとします。
constexpr char INSTANCE_NAME[]{"FOO"};
struct Struct{ void function() const { std::cout << __PRETTY_FUNCTION__; } };
std::ostream &operator <<(std::ostream &o, const Struct &) { return o << INSTANCE_NAME; }
template <const char *> char Value[]{"UNKNOWN"};
// spezialization when the pointer is INSTANCE_NAME
template < > Struct Value<INSTANCE_NAME>{};
テンプレート変数は、特殊化に応じて異なる型を持つことに注意してください。10 には 2 つのテンプレート関数があり、それぞれがconst char *
非テンプレート引数として受け取り、それを変数テンプレートに転送します。
template <const char *NAME> void print()
{
std::cout << Value<NAME> << '\n';
}
template <const char *NAME> void call_function()
{
Value<NAME>.function();
}
次に、この関数を呼び出すと、異なる動作が発生します。
int main()
{
print<INSTANCE_NAME>();
call_function<INSTANCE_NAME>();
return 0;
}
clang 3.7.0 は(私が予想していたように) を出力しFOO
、void Struct::function() const
gcc 6.0.0 は以下のエラーでコンパイルに失敗します:
非クラス タイプ 'char [8]' である 'Value' のメンバー 'function' の要求
gcc がテンプレートの非型引数を関数内の変数テンプレートに転送できなかったことはほぼ確実です。このため、型を持つ特殊化されていない変数テンプレートを選択します...NAME
Value
call_function
'char [8]'
テンプレート引数をコピーしているように動作しています。これは、オブジェクトのメンバー関数を呼び出した場合にのみ発生します。の本体をコメント化するとcall_function
、出力はFOO
notUNKNOWN
になるため、print
関数内では gcc でも転送が機能します。
そう
- 正しい動作は何ですか?(mi ベットは clang 用です)
- 間違ったことをしているコンパイラのバグチケットを開くにはどうすればよいですか?