Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this call of overloaded function ambiguous?

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?

like image 444
mskr Avatar asked Oct 30 '25 13:10

mskr


1 Answers

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::function from the lambdas are identical. The standard specifies that the function object given to std::function "shall be Callable (20.8.11.2) for argument types ArgTypes and return type R." 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; }
like image 137
user5900716 Avatar answered Nov 02 '25 02:11

user5900716