In C++17 noexcept
has been added to the type system:
void r1( void (*f)() noexcept ) { f(); } void foo() { throw 1; } int main() { r1(foo); }
The latest versions of GCC and Clang in C++17 mode reject the call r1(foo)
, because void (*)()
cannot be implicitly converted to void (*)() noexcept
.
But with std::function
instead:
#include <functional> void r2( std::function<void() noexcept> f ) { f(); } void foo() { throw 1; } int main() { r2(foo); }
Clang accepts the program, apparently ignoring the noexcept
specifier; and g++
gives a strange error regarding std::function<void() noexcept>
.
What is the correct behaviour for this second program in C++17?
The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions. It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.
noexcept means that a function will not throw, not that it cannot throw, and the penalty for failure to comply is calling std::terminate , not UB.
noexcept is for compiler performance optimizations in the same way that const is for compiler performance optimizations. That is, almost never. noexcept is primarily used to allow "you" to detect at compile-time if a function can throw an exception.
The noexcept specification is equivalent to the noexcept(true) specification. throw() is equivalent to noexcept(true) but was deprecated with C++11 and will be removed with C++20. In contrast, noexcept(false) means that the function may throw an exception.
std::function
's definition hasn't changed in the current working draft:
template<class T> class function; // not defined template<class R, class... ArgTypes> class function<R(ArgTypes...)> { /* ... */ };
Since void() noexcept
doesn't match the partial specialization, std::function<void() noexcept>
is an incomplete type. Both Clang and GCC trunk diagnose this accordingly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With