Exception safety of std::function initialized by a function pointer

mentalmushroom

The constructor of std::function is not declared noexcept:

template< class F > function( F f );

On the other hand, C++ reference mentions the following:

Does not throw if f is a function pointer or a std::reference_wrapper, otherwise may throw std::bad_alloc or any exception thrown by the copy constructor of the stored callable object.

Does it mean that the constructor of the following class can be safely declared noexcept since I initialize std::function with a pointer to a static member function?

class Worker
{
public:    
    Worker() noexcept {} // ok?
    void test() { reporter("test"); }
private:
    static void dummy(const std::string& ) {};
    std::function<void (const std::string&)> reporter = &dummy; // doesn't throw an exception?
};

int main()
{
    Worker w;
    w.test();
}

And if std::function member were constructed from a lambda, declaring the constructor noexcept would be wrong?

class Worker
{
public:    
    Worker() noexcept {} // bad?
    void test() { reporter("Test"); }
private:
    std::function<void (const std::string&)> reporter = [](const std::string& ){}; // may throw?
};

I have also noticed that GCC gives an error when the constructor declared noexcept is defaulted, because its exception specification does not match the implicit exception specification, which is noexcept(false) due to std::function constructor not being declared noexcept.

class Worker
{
public:
    Worker() noexcept = default; // this won't compile    
    void test() { reporter("test"); }
private:
    static void dummy(const std::string& ) {};
    std::function<void (const std::string&)> reporter = &dummy;
};
Acorn

Does it mean that the constructor of the following class can be safely declared noexcept since I initialize std::function with a pointer to a static member function?

Note that it's always "safe" to declare a function noexcept. The program will terminate if an exception is thrown, but it isn't undefined behavior.

But yes, in your case, no exceptions should be thrown, so no termination of the program should happen. The standard says: "Throws: Nothing if f is ... a function pointer. ..."

And if std::function member were constructed from a lambda, declaring the constructor noexcept would be wrong?

Yes, it'd be "wrong" in the sense you want (the program will terminate if it throws), because a lambda isn't a function pointer. Instead, prefix the lambda with the unary operator+ to make it a function pointer:

std::function<void (const std::string&)> reporter = +[](const std::string& ){};

And I'd probably mention this in a comment, in particular if you did not comment why the constructor is noexcept.

I have also noticed that GCC gives an error when the constructor declared noexcept is defaulted

The latest versions of both GCC and Clang do not give an error, so if that is true it is perhaps a Defect Report that was issued on the standard.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Function Pointer - variable not initialized

Check if a pointer to function is initialized

make function pointer in class dependent on initialized value

std::function function vs function pointer

passing pointer to std::function<void()>

Can std::function have a function pointer as the type?

Ambiguous overload on function pointer and std::function

std::function to C-style function pointer

How to convert std::function to function pointer?

std::function pointer error: cannot convert &A::a to type std::function<>&&

smart pointer as argument of function which uses std::function, std::bind

Is it safe to change a function pointer (std::function) inside a called function?

Passing (partially) templated template function as std::function(or function pointer)

c++11 std::hash function object classes thread safety

Using a pointer arg to my function throws an exception

C++ , function pointer exception error

Why ampersand in `std::is_member_function_pointer`?

template types in std is_member_function_pointer

`std::enable_if` is function pointer - how?

Auto variable to store function pointer to std::max

Function pointer in a std::thread Args... list

Invoking std::thread with pointer to freestanding function

Pointer to member function-object in std::invoke

How to call the lambda stored in pointer to the `std::function`?

std::invoke substitution failure for member function pointer

C++ std array of function pointer syntax

Raise an exception if a variable is accessed before being "initialized" by another function

function pointer is not a function or function pointer

strtok function thread safety