xmllmx
xmllmx

Reputation: 42379

Why does 'std::function<void()>' take a lambda returning 'bool' without any warning?

#include <functional>

void f()
{
    // warning: return-statement with a value, in function returning 'void'
    return true; 
}

std::function<void()> fn = [] { return true; }; // no warning

int main()
{}

Why does std::function<void()> take a lambda returning bool without any warning?

Upvotes: 0

Views: 433

Answers (2)

Pete Becker
Pete Becker

Reputation: 76428

That's its job: it handles impedance matching between the declared type of the function object and the callable object that it holds.

Ordinary pointers to function are strictly typed:

int f(double);
double g(int);

int x = f(3.2); // OK
long y = f(3);  // OK: argument and return type get converted

int (*ptr)(double);
ptr = f; // OK: f is pointer to function taking double and returning int
ptr = g; // error: types don't match

std::function handles type mismatches, so type conversions look more like what you expect in a function call:

std::function<int(double)> func;
func = f; // OK
func = g; // OK: argument and return type get converted internally

This flexibility comes at a cost, so when you are dealing with exact types you should use function pointers and not std::function.

Upvotes: 1

HolyBlackCat
HolyBlackCat

Reputation: 96579

Because that's how it's designed. If the return type in the template argument is void, it ignores the return type of the functor.

This is in line with how std::is_invocable_r works.

Also, it would be hard for a (non-magical) class to emit a warning. (Unlike failing with an error, which is easy.) Not to mention that the standard doesn't differentiate warnings from errors.

Upvotes: 3

Related Questions