异常规范和模板
Exception specifications and templates
以下代码段被 clang 拒绝:
template <typename T> void foo() noexcept {}
template <typename T> void bar() throw() {}
template void foo<int>();
template void bar<int>();
使用 clang++ -std=c++1z -c
我得到:
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 trunk 接受带有 -std=c++1z
的代码。
哪个编译器是正确的?
Clang 的解决方法是指定异常 spec:
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:
The noexcept-specification is a part of the function type and may
appear as part of any function declarator. since C++17
标准的较长版本:(最新草案)[except.spec/5] ...(强调我的)。
If any declaration of a function has an exception-specification that
is not a noexcept-specification allowing all exceptions, all
declarations, including the definition and any explicit
specialization, of that function shall have a compatible
exception-specification. If any declaration of a pointer to function,
reference to function, or pointer to member function has an
exception-specification, all occurrences of that declaration shall
have a compatible exception-specification. If a declaration of a
function has an implicit exception specification, other declarations
of the function shall not specify an exception-specification. In an
explicit instantiation an exception-specification may be specified,
but is not required. If an exception-specification is specified in an
explicit instantiation directive, it shall be compatible with the
exception-specifications of other declarations of that function. A
diagnostic is required only if the exception-specifications are not
compatible within a single translation unit.
以下代码段被 clang 拒绝:
template <typename T> void foo() noexcept {}
template <typename T> void bar() throw() {}
template void foo<int>();
template void bar<int>();
使用 clang++ -std=c++1z -c
我得到:
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 trunk 接受带有 -std=c++1z
的代码。
哪个编译器是正确的?
Clang 的解决方法是指定异常 spec:
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:
The noexcept-specification is a part of the function type and may appear as part of any function declarator. since C++17
标准的较长版本:(最新草案)[except.spec/5] ...(强调我的)。
If any declaration of a function has an exception-specification that is not a noexcept-specification allowing all exceptions, all declarations, including the definition and any explicit specialization, of that function shall have a compatible exception-specification. If any declaration of a pointer to function, reference to function, or pointer to member function has an exception-specification, all occurrences of that declaration shall have a compatible exception-specification. If a declaration of a function has an implicit exception specification, other declarations of the function shall not specify an exception-specification. In an explicit instantiation an exception-specification may be specified, but is not required. If an exception-specification is specified in an explicit instantiation directive, it shall be compatible with the exception-specifications of other declarations of that function. A diagnostic is required only if the exception-specifications are not compatible within a single translation unit.