mercredi 3 février 2021

Forcing C++ to prefer an overload with an implicit conversion over a template

I have a situation where I need overload resolution to prefer an overload with an implicit conversion over a template function with the same name.

Consider the following example:

#include <iostream>
#include <functional>

void call_function(const std::function<void()>& function)
{
   std::cout << "CALL FUNCTION 1" << std::endl;
   function();
}

template <typename Function>
void call_function(const Function& function)
{
    std::cout << "CALL FUNCTION 2" << std::endl;
    function();
}

int main()
{
    // Pass a lambda to "call_function"
    // This lambda is implicitly convertible to 'std::function<void()>'
    // Even though it is implicitly convertible, the template function is selected by the compiler.
    call_function([]{
        std::cout << "TEST" << std::endl;
    });
}

Output:

CALL FUNCTION 2
TEST

Unfortunately, the compiler seems to detect that the first implementation of call_function would require an implicit conversion to convert the lambda I pass it into a std::function<void()> object and because of this it determines that the template version is a better match and uses the template. I need to force the compiler to prefer the implicit conversion overload over the template so the output would be:

CALL FUNCTION 1
TEST

How can I achieve this? (Also note that I am restricted to a C++11 compliant compiler so I am unable to use features from C++14 and beyond)

Aucun commentaire:

Enregistrer un commentaire