c++11 - Resolving ambiguous overload on function pointer and std::function for a lambda using + -
in following code, first call foo
ambiguous, , therefore fails compile.
the second, added +
before lambda, resolves function pointer overload.
#include <functional> void foo(std::function<void()> f) { f(); } void foo(void (*f)()) { f(); } int main () { foo( [](){} ); // ambiguous foo( +[](){} ); // not ambiguous (calls function pointer overload) }
what +
notation doing here?
the +
in expression +[](){}
unary +
operator. defined follows in [expr.unary.op]/7:
the operand of unary
+
operator shall have arithmetic, unscoped enumeration, or pointer type , result value of argument.
the lambda not of arithmetic type etc., can converted:
[expr.prim.lambda]/3
the type of lambda-expression [...] unique, unnamed non-union class type — called closure type — properties described below.
[expr.prim.lambda]/6
the closure type lambda-expression no lambda-capture has
public
non-virtual
non-explicit
const
conversion function pointer function having same parameter , return types closure type's function call operator. value returned conversion function shall address of function that, when invoked, has same effect invoking closure type’s function call operator.
therefore, unary +
forces conversion function pointer type, lambda void (*)()
. therefore, type of expression +[](){}
function pointer type void (*)()
.
the second overload void foo(void (*f)())
becomes exact match in ranking overload resolution , therefore chosen unambiguously (as first overload not exact match).
the lambda [](){}
can converted std::function<void()>
via non-explicit template ctor of std::function
, takes type fulfils callable
, copyconstructible
requirements.
the lambda can converted void (*)()
via conversion function of closure type (see above).
both user-defined conversion sequences, , of same rank. that's why overload resolution fails in first example due ambiguity.
according cassio neri, backed argument daniel krügler, unary +
trick should specified behaviour, i.e. can rely on (see discussion in comments).
still, i'd recommend using explicit cast function pointer type if want avoid ambiguity: don't need ask on , why works ;)
Comments
Post a Comment