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值
您可以使用extrastd::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
insideexplicit\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