C++:采用右值引用的模板函数重载非模板函数

C++: Template Function taking rvalue reference overloads non-template function

正在尝试 运行 一个非泛型函数,但它被模板函数重载了。

问题是他们将右值引用作为参数。


这是它的样子:

#include <iostream>
using namespace std;

template <typename T> void bar(T &b)  { cout << "bar <template> called\n" ; }
template <typename T> void foo(T &&b) { cout << "foo <template> called\n" ; }
void bar(string &b)                   { cout << "bar <string> called\n"   ; }
void foo(string &&b)                  { cout << "foo <string> called\n"   ; }

int main() {

    string msg_a = "hello a";
    string msg_b = "hello b";
    int a = 1;
    int b = 2;

    bar(a);
    bar(msg_a);

    bar(b);
    bar(msg_b);

    cout << "\n";

    foo(a);
    foo(msg_a); // <-- I want this to call the 'void foo(string &&b)' but it doesn't

    foo(b);
    foo(msg_b); // <-- I want this to call the 'void foo(string &&b)' but it doesn't

    return (0);
}
Output:

bar <template> called
bar <string> called
bar <template> called
bar <string> called

foo <template> called
foo <template> called
foo <template> called
foo <template> called

当我用类型 string 调用 foo() 时,我希望它调用 void foo(string &&b) 函数,但它调用 template <typename T> void foo(T &&b) 函数。

然而正如您所看到的采用 左值引用的函数 这不是问题并且优先级保持正常。


有谁知道解决方法或变通方法吗?

foo(msg_a) 永远不能调用 void foo(string &&b),因为那个特定的重载只接受类型 stringrvalues,而 msg_alvalue 表达式。因此,唯一可行的回退是 template <typename T> void foo(T &&b),它接受 转发引用 。转发引用绑定到 lvaluesrvalues.

如果您使用 rvalue(例如 foo(std::string{}))调用 foo,那么它将调用上述重载。