Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't overload resolution picking the std::vector overload of my template function?

Tags:

c++

templates

In the following code, I want it to use the std::vector version of f() if I call it with a std::vector argument, but it's using the first one and complaining that std::to_string(const std::vector<T>&) doesn't exist. My understanding of template overload resolution is that it should use the "more specialized" version. Somehow I think that doesn't apply here, because this is a function overload rather than a template overload. But it's not even using the normal function overload resultion rules, or else it would complain about an ambiguous call to f().

#include <vector>
#include <string>

template<typename T>
std::string f(T&& member) {
    return std::to_string(member);
}

template<typename T>
std::string f(const std::vector<T>& member) {
    return std::to_string(member[0]);
}

int main() {
    int a = 42;
    printf("%s\n", f(a).c_str()); // OK

    std::vector<int> b = { 42 };
    printf("%s\n", f(b).c_str()); // ERROR: to_string doesn't have a std::vector overload

    return 0;
}

What am I doing wrong?

like image 556
Jorge Rodriguez Avatar asked Jul 18 '19 04:07

Jorge Rodriguez


1 Answers

The type deduced by the forwarding reference is std::vector<int>&, as opposed to the const std::vector<int>& of the other overload. So when comparing the overloads, your non-const argument is a better match for the non-const qualified reference parameter, and so that one is chosen.

One way to address it is to account for both const qualifications with the help of another overload.

template<typename T>
std::string f(std::vector<T>& member) {
    return f(std::as_const(member));
}

Here we obtain a const reference to member with the help of std::as_const and delegate to your original overload. You may want to provide an rvalue specific overload too, since the forwarding reference will deduce a better match for those as well when compared to your vector overloads.

like image 156
StoryTeller - Unslander Monica Avatar answered Nov 09 '22 14:11

StoryTeller - Unslander Monica