octoploid octoploid - 11 days ago 7
C++ Question

Exception specifications and templates

The following snippet is rejected by clang:

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


With
clang++ -std=c++1z -c
I get:

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 accepts the code with
-std=c++1z
.
Which compiler is right?

live example

Answer

In C++17, for it to work, you will have to instantiate them this way:

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

See it Live here

This is because, starting from C++17, exception specifications are now part of a function's signature. To quote Cppreference:

The noexcept-specification is a part of the function type and may appear as part of any function declarator. since C++17

The longer version from the standard: (Latest draft) [except.spec/5] ...Its a long reading.

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.

Comments