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

Popular posts from this blog

javascript - DIV "hiding" when changing dropdown value -

Does Firefox offer AppleScript support to get URL of windows? -

android - How to install packaged app on Firefox for mobile? -