Reputation: 2467
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;
};
Upvotes: 1
Views: 175
Reputation: 26076
Does it mean that the constructor of the following class can be safely declared
noexcept
since I initializestd::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 constructornoexcept
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.
Upvotes: 1