Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my function overload not preferred over my templated one?

According to the first answer to this question: function template overloading, a "A non-templated (or "less templated") overload is preferred to templates".

#include <iostream>
#include <string>
#include <functional>

void f1(std::string const& str) {
    std::cout << "f1 " << str << "\n";
}

template <typename Callback, typename... InputArgs>
void call(Callback callback, InputArgs ...args) {
    callback(args...);
}

void call(std::function<void(std::string const&)> callback, const char *str) {
    std::cout << "custom call: ";
    callback(str);
}

int main() {
    auto f2 = [](std::string const& str) -> void {
        std::cout << "f2 " << str << "\n";
    };

    call(f1, "Hello World!");
    call(f2, "Salut Monde !");

    return 0;
}

Where, as far as I understand it, the second definition of call is "non-templated", and thus should be chosen over the first one when I do call(f1, "1") or call(f2, "2").

This is not the case, I get the following output:

f1 Hello World!
f2 Salut Monde !

If I remove the templated version of call, I get the expected output.

Why is my overload of call not chosen over the first one in this case?

like image 256
Holt Avatar asked Dec 15 '22 08:12

Holt


2 Answers

The types for f1 and f2 are not std::function, a user defined conversion is needed, thus the template version is chosen instead.

If you did provide a function call that is an exact match for a function pointer, such as;

void call (void(*callback)(std::string const&), const char *str)

It would be chosen for f1.


Note: with the addition of the unary + on the lambda, you can also get a function pointer in this case (your capture list is empty)...

auto f2 = +[](std::string const& str) -> void
//        ^ unary +
like image 104
Niall Avatar answered Dec 29 '22 00:12

Niall


The type of the lambda f2 is not std::function<void(std::string const&)>, it is a compiler generated type. Therefore the templated call provided a better match.

like image 20
Daniel Avatar answered Dec 28 '22 23:12

Daniel