Disambiguating calls to functions taking std::functions

前端 未结 2 618
一向
一向 2021-01-13 08:17

The code below doesn\'t compile on gcc 4.5 because the call to foo is ambiguous. What is the correct way to disambiguate it?

#include 
#         


        
2条回答
  •  情深已故
    2021-01-13 08:54

    The best way is to explicitly create a std::function object of the correct type then pass that object to the function:

    std::function func = 
        [](int a, int b) { cout << "a: " << a << " b: " << b << endl; }
    foo(func);
    

    or inline:

    foo(
        std::function(
            [](int a, int b) { cout << "a: " << a << "b: " << b << endl; }
    ));
    

    std::function has a constructor template that accepts anything:

    template function(F);
    

    Because of this, there's no way for the compiler to know during overload resolution which foo to select: both std::function and std::function have a constructor that can take your lambda expression as an argument.

    When you pass a std::function object directly, the std::function copy constructor is preferred during overload resolution, so it is selected instead of the constructor template.


    Answer for the future: If the capture list is guaranteed to be empty, you can also use ordinary function pointers. In C++0x, a captureless lambda is implicitly convertible to a function pointer. So, you can use something like

    void foo(void (*t)(int, int)) { t(1, 2); }
    
    void foo(void (*t)(int)) { t(1); }
    

    and call foo directly with the captureless lambda (or a function pointer with matching type).

    Note that this conversion is a very recent addition to the draft language standard (it was added in February of this year), so it is not likely to be widely supported yet. Visual C++ 2010 doesn't support it yet; I don't know about the latest g++.

提交回复
热议问题