为什么重载解析不选择模板函数的std :: vector重载?

Jor*_*uez 5 c++ templates

在下面的代码中,如果要通过参数调用它,我希望它使用的std::vector版本,但是它使用的是第一个,并且抱怨不存在。我对模板重载解决方案的理解是,它应该使用“更专业”的版本。我认为这不适用于这里,因为这是函数重载而不是模板重载。但是它甚至没有使用正常的函数重载结果规则,否则会抱怨对的模棱两可。f()std::vectorstd::to_string(const std::vector<T>&)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;
}
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

Sto*_*ica 5

与其他重载的类型std::vector<int>&相反,转发引用推导的类型为const std::vector<int>&。因此,在比较重载时,您的非常量参数与非常量限定引用参数更匹配,因此可以选择一个。

解决该问题的一种方法是在另一个重载的帮助下考虑两个const资格。

template<typename T>
std::string f(std::vector<T>& member) {
    return f(std::as_const(member));
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们member在的帮助下获得const引用,std::as_const并委托给您原始的重载。您可能还希望提供特定于右值的重载,因为与重载相比,转发参考也将得出更好的匹配vector