Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::function with noexcept in C++17

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?

like image 477
M.M Avatar asked Dec 22 '16 23:12

M.M


People also ask

What is noexcept used for in c++?

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.

What happens when Noexcept function throws?

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.

What does const noexcept mean?

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.

Is Noexcept a C++?

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.


1 Answers

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.

like image 55
T.C. Avatar answered Oct 02 '22 11:10

T.C.