Ambiguity Resolution in Function Overloading Using Unary Plus
In the given code snippet:
void foo(std::function<void()> f) { f(); } void foo(void (*f)()) { f(); } int main() { foo([]() {}); // ambiguous foo(+[]() {}); // not ambiguous (calls the function pointer overload) }
The first call to foo with the lambda expression as an argument fails to compile due to ambiguity. However, the second call with the unary before the lambda resolves to the function pointer overload.
The Role of Unary Plus
The operator used in [] is the unary plus operator. It is defined in the C standard as converting an operand of arithmetic, unscoped enumeration, or pointer type to the operand's value.
In this case, although the lambda expression is not of an arithmetic type, it can be converted to a function pointer type.
Conversion to Function Pointer Type
According to the C standard, a lambda expression with no lambda capture has a public conversion function to pointer to function with the same parameter and return types as the lambda's function call operator.
Therefore, the unary forces the conversion of the lambda expression to the function pointer type, void (*)().
Overload Resolution
The second overload, void foo(void (*f)()), becomes an exact match in overload resolution because the argument type, void (*)(), matches the parameter type. The first overload, void foo(std::function
As a result, the second overload is unambiguously chosen, resolving the ambiguity in the first call.
Considerations
While the unary trick for resolving overload ambiguity is not explicitly specified in the C standard, it is generally considered to be reliable behavior.
However, it is recommended to use an explicit cast to the function pointer type to avoid any potential confusion or future changes in the standard's interpretation.
The above is the detailed content of How does the Unary Plus Operator Resolve Ambiguity in Function Overloading with Lambda Expressions?. For more information, please follow other related articles on the PHP Chinese website!