【问题标题】:Why isn't overload resolution picking the std::vector overload of my template function?为什么重载分辨率不选择我的模板函数的 std::vector 重载?
【发布时间】:2019-07-18 04:59:39
【问题描述】:

在下面的代码中,如果我使用std::vector 参数调用它,我希望它使用std::vector 版本的f(),但它使用第一个并抱怨std::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;
}

我做错了什么?

【问题讨论】:

  • 如果没有必要,重载解析宁愿不添加 cv-qualification。

标签: c++ templates


【解决方案1】:

转发引用推导出的类型是std::vector&lt;int&gt;&amp;,而不是其他重载的const std::vector&lt;int&gt;&amp;。因此,在比较重载时,您的非 const 参数更适合非 const 限定引用参数,因此选择了一个。

解决这个问题的一种方法是在另一个重载的帮助下同时考虑两个 const 限定条件。

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

在这里,我们在std::as_const 的帮助下获得了对member 的常量引用,并委托给您原来的重载。您可能还想提供一个右值特定的重载,因为与您的 vector 重载相比,转发引用也会推断出更好的匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-22
    • 2015-09-12
    • 2023-03-27
    • 1970-01-01
    相关资源
    最近更新 更多