2016-11-20 4 views
3

次のスニペットを打ち鳴らすによって拒否されていますclang++ -std=c++1z -c例外仕様およびテンプレート

template <typename T> void foo() noexcept {} 
template <typename T> void bar() throw() {} 
template void foo<int>(); 
template void bar<int>(); 

私が手:

compat.ii:3:15: error: explicit instantiation of 'foo' does not refer to a function template, variable template, member function, member class, or static data member 
template void foo<int>(); 
      ^
compat.ii:1:28: note: candidate template ignored: could not match 'void() noexcept' against 'void()' 
template <typename T> void foo() noexcept {} 
         ^
compat.ii:4:15: error: explicit instantiation of 'bar' does not refer to a function template, variable template, member function, member class, or static data member 
template void bar<int>(); 
      ^
compat.ii:2:28: note: candidate template ignored: could not match 'void() throw()' against 'void()' 
template <typename T> void bar() throw() {} 
         ^
2 errors generated. 

gccのトランクは-std=c++1zでコードを受け付けます。 正しいコンパイラは?

live example

+0

'void foo 'と 'throw()'に 'noexcept'を' void bar 'に追加するとClangが動作すると思いますか? – ildjarn

+0

私のトランクgccはそのようなコードを拒否します。ワンドボックスもそうです。 – krzaq

答えて

2

クランのための回避策は例外スペック指定することです:

template <typename T> void foo() noexcept {} 
template <typename T> void bar() throw() {} 
template void foo<int>() noexcept; 
template void bar<int>() throw(); 

ものの、C++ 17から開始し、例外仕様は現在、関数のシグネチャの一部であり、それはあります明示的なインスタンス化には必要ありません。 Cppreferenceを引用すると:

をnoexcept仕様は、関数型の一部であり、 任意の関数宣言子の一部として表示されることがあります。 C++以降17

標準より長いバージョン:(最新ドラフト)[except.spec/5] ...(強調するマイン)。

機能の任意宣言が はすべての例外を可能にnoexcept仕様ない例外指定されている場合、その関数の定義と明示的 特殊を含むすべて 宣言は、互換性を持たなければならない 例外仕様。関数へのポインタの宣言、関数への参照、または関数へのポインタが 例外仕様を持つ場合、その宣言のすべての出現は、互換性のある例外仕様を持つものとする。 関数の宣言が暗黙の例外仕様を持つ場合、その関数の他の宣言 は例外仕様を指定してはならない。 明示的なインスタンス化では、例外仕様が指定されている可能性がありますが、これは必須ではありません。 明示的インスタンス化指令に例外仕様が指定されている場合は、その関数の他の宣言の例外仕様と互換性があります。 A 診断は、例外仕様が単一の翻訳単位内で互換性のある でない場合にのみ必要です。

+2

さて、明示的なインスタンス化では、例外仕様を指定することはできますが、必須ではありません。 "使用されていて互換性がない場合にのみ、単一のCUに診断が必要です。 それは私にはクラングバグのように見えます。 – octoploid

+1

私はhttps://llvm.org/bugs/show_bug.cgi?id=31081 – octoploid

+0

@octoploidを開いています。私は私の答えを改訂しました – WhiZTiM

関連する問題