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

时间:2019-08-10 00:12:56

标签: c++ rvalue-reference function-templates

尝试运行非泛型函数,但模板函数会重载该函数。

问题在于它们将右值引用作为参数。


这有点像:

#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

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

使用带有左值引用的函数可以看到,这不是问题,并且优先级保持正常。


有人知道这个问题的解决方法吗?

1 个答案:

答案 0 :(得分:4)

foo(msg_a)永远无法调用void foo(string &&b),因为特定的重载仅接受类型为string rvalues ,而msg_a lvalue 表达式。因此,唯一可行的回退是template <typename T> void foo(T &&b),它接受​​转发参考。转发引用绑定到 lvalues rvalues

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