Why is this constructor call ambiguous?
#include <functional>
class A {
std::function<int(void)> f_;
std::function<float(void)> g_;
public:
A(std::function<int(void)> f) { f_ = f; }
A(std::function<float(void)> g) { g_ = g; }
~A() {}
};
int main()
{
A a([](){ return (int)1; });
return 0;
}
Note the typecast.
Is there a way to tell the compiler which constructor overload to use?
It's a defect in the standard. See DR 2132:
Consider the following:
#include <functional> void f(std::function<void()>) {} void f(std::function<void(int)>) {} int main() { f([]{}); f([](int){}); }The calls to f in main are ambiguous. Apparently because the conversion sequences to
std::functionfrom the lambdas are identical. The standard specifies that the function object given tostd::function"shall be Callable (20.8.11.2) for argument typesArgTypesand return typeR." It doesn't say that if this is not the case, the constructor isn't part of the overload set.
Try using a function pointer as an argument instead:
A(int f()) { f_ = f; }
A(float g()) { g_ = g; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With