C++ 为什么编译器不';t选择“forward”的右值引用版本?

C++ 为什么编译器不';t选择“forward”的右值引用版本?,c++,perfect-forwarding,C++,Perfect Forwarding,我编写了一个类似的std::forward实现,希望找出编译器将选择哪个版本。问题是它似乎从不选择右值引用版本 #include <type_traits> #include <iostream> #include <string> #include <utility> using std::string; using std::cout; using std::endl; using std::remove_reference; using s

我编写了一个类似的
std::forward
实现,希望找出编译器将选择哪个版本。问题是它似乎从不选择右值引用版本

#include <type_traits>
#include <iostream>
#include <string>
#include <utility>

using std::string;
using std::cout;
using std::endl;
using std::remove_reference;
using std::move;

namespace explicit_return {
template <typename type> type&& forward(typename remove_reference<type>::type&  value) { cout << "cp-"; return static_cast<type&&>(value); }
template <typename type> type&& forward(typename remove_reference<type>::type&& value) { cout << "mv-"; return static_cast<type&&>(value); }
}

void print(string const & value) { cout << "c:" << value << endl; }
void print(string &  value)      { cout << "l:" << value << endl; }
void print(string && value)      { cout << "r:" << value << endl; }

template <typename type> void explicit_print(type && value) {          print(explicit_return::forward<type>(value)); }
template <typename type> void indirect_print(type && value) { explicit_print(explicit_return::forward<type>(value)); }

int main()
{
    string a("perfect");
    indirect_print(a);
    indirect_print(move(a));
    indirect_print("forward");
}


传递给
forward
的参数是一个变量,因此是一个
l值

您可以使用extra
std::move
或extra forward选择r值重载,例如:

template <typename type> void print_forward2(type&& value)
{
     print(explicit_return::forward<type>(explicit_return::forward<type>(value)));
}

尽管您已将
间接打印
参数声明为
类型&
,但其值类不是右值,而是左值。任何命名对象都是左值

template <typename type>
void indirect_print(type && value) {
  explicit_print(explicit_return::forward<type>(value)); // `value` is lvalue here
}
你会看到区别:

cp-r:perfect
mv-r:perfect
mv-r:forward

value
inside
explicit\u print
是命名对象,因此它被视为左值。这就是为什么总是选择向前(类型&)
。如果你想选择
forward(type&&)
你必须将
value
转换为右值引用。是的,我明白了,只是想知道为什么我们甚至需要
forward(type&&)
?谢谢,有意义。还是有点神秘,你是说打印(std::forward(std::move(std::get(my_tuple))…)?@LanceLI:No,
std::get
对右值
元组有重载。但我认为有相当的表达。
template <typename type>
void indirect_print(type && value) {
  explicit_print(explicit_return::forward<type>(value)); // `value` is lvalue here
}
int main()
{
    string a("perfect");

    print(explicit_return::forward<std::string>(a));
    print(explicit_return::forward<std::string>(move(a)));
    print(explicit_return::forward<std::string>("forward"));
}
cp-r:perfect
mv-r:perfect
mv-r:forward