最新のclang(バージョン3.4トランク187493)がコンパイルに失敗する非常に単純な(C++11)コードがありますが、GCCは正常にコンパイルされます。
コード (以下) は、function-templatefoo
をfunction-local 型 Bar
でインスタンス化し、そのアドレスを class-template の非型テンプレート パラメーターとして使用しようとしますFunc
。
template<void(*FUNC_PTR)(void)>
struct Func {};
template<typename T> extern inline
void foo() {
using Foo = Func<foo<T>>;
}
int main() {
struct Bar {}; // function-local type
foo<Bar>();
return 0;
}
clang は次のエラーを出力します。
エラー: 非型のテンプレート引数がリンケージを持たない関数 'foo' を参照しています
ただし、型Bar
をグローバル スコープに移動すると (関数から取り出すことによって)、clang はそれを正常にコンパイルし、型がfunction-localであることが問題であることを証明します。
それで、clang はこのエラーを出力するのが正しいですか、それとも標準はこれをサポートしていませんか (その場合、GCC はそれを許可することで寛大すぎます)?
編集 #1:明確にするために、「ローカル型をテンプレート パラメーターとして使用できない」という制限が C++11 で削除されたため、これはこの質問の複製ではありません。ただし、ローカル型の使用に関連するリンケージの影響があるかどうか、およびこのエラーの発生において clang が正しいかどうかはまだ不明です。
編集 #2 :上記のコードのエラーを出力するのは clang が正しかった (@jxh からの回答を参照) が、次のコードのエラーも誤って出力すると判断されました (スコープからスコープに
using
移動された宣言を使用):foo<Bar>()
main()
template<void(*FUNC_PTR)(void)>
struct Func {};
template<typename T> extern inline
void foo() {}
int main() {
struct Bar {};
using F = Func<foo<Bar>>;
return 0;
}