C++ 前向参考混淆
关于下面的代码,我不理解为什么调用C++ 前向参考混淆,c++,c++11,c++14,C++,C++11,C++14,关于下面的代码,我不理解为什么调用移动构造函数时同时使用左值和右值。当我将lvalue传递给push方法时,我希望打印copy-ctor #include <iostream> #include <string> #include <vector> using namespace std; class my_obj { public: my_obj() { cout << "default ctor\n";
移动构造函数
时同时使用左值
和右值
。当我将lvalue
传递给push
方法时,我希望打印copy-ctor
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class my_obj
{
public:
my_obj()
{
cout << "default ctor\n";
}
my_obj(const my_obj& other)
{
cout << "copy ctor\n";
}
my_obj(my_obj&& other)
{
cout << "move ctor\n";
}
};
class test
{
public:
template<typename T>
void push(T&& object)
{
print(forward<T>(object));
}
template<typename T>
void print(T&& a)
{
cout << "move\n";
my_obj temp = forward<T>(a);
}
template<typename T>
void print(T& a)
{
cout << "val\n";
my_obj temp = forward<T>(a);
}
};
int main()
{
my_obj obj;
test f;
f.push(obj); // why is move ctor called here? shouldnt it be copy ctor since not rvalue
cout << "\nPUSHING TEMP\n\n";
f.push(my_obj {});
}
调用移动构造函数是因为您正在使用
std::forward
而没有转发引用(请不要这样做)。基本上,这条线是罪魁祸首:
my_obj temp = forward<T>(a);
因此,您正在将
a
强制转换为右值引用,并且右值具有移动语义,因此您可以看到正在调用移动构造函数。您基本上得到了std::move
的行为,调用move构造函数是因为您使用的std::forward
没有转发引用(请不要这样做)。基本上,这条线是罪魁祸首:
my_obj temp = forward<T>(a);
因此,您正在将a
强制转换为右值引用,并且右值具有移动语义,因此您可以看到正在调用移动构造函数。在这里,您基本上得到了std::move
的行为:
template<typename T>
void print(T& a)
{
cout << "val\n";
my_obj temp = forward<T>(a);
}
模板
作废打印(T&a)
{
不能在这里:
template<typename T>
void print(T& a)
{
cout << "val\n";
my_obj temp = forward<T>(a);
}
模板
作废打印(T&a)
{
@pyjg没有理由感到愚蠢。每个人都必须在某个时候学会这一点。因此,正确的修复方法应该是在该函数中使用my_obj temp=a;
。@pyjg是的。转发的目的是保留值类别,但这里我们知道我们有一个左值。通常,你只想转发转发引用,而你没有一,所以不要转发(正确的转发应该是转发(a)
,但请不要写)。明白了,谢谢你的解释。它现在很有意义:)@pyjg没有理由感到愚蠢。每个人都必须在某个时候学习这一点。所以正确的修复方法是在该函数中使用my_obj temp=a;
。@pyjg是的。转发的目的是保留值类别,但这里我们知道我们有一个左值。通常,你只想forward
forwarding references-你没有,所以不要forward
(“正确”的转发应该是forward(a)
,但请不要真的写)。明白了,谢谢你的解释,现在很有意义:)