威尔 C++使用复制赋值运算符中的移动构造函数?
假设我有一个简单的结构,其中包含一个向量并定义一个复制赋值运算符,以及一个返回该结构的函数,如下所示:
struct SimpleStruct
{
vector< int > vec1;
operator=( SimpleStruct& other )
{
vec1 = other.vec1;
}
}
SimpleStruct GetStruct();
据我了解,因为我已经声明了一个复制赋值运算符,所以编译器不会自动生成SimpleStruct 的移动构造函数。
因此,如果我像这样使用 GetStruct 函数:
SimpleStruct value = GetStruct();
当我说 vec1 = other.vec1; 时,编译器是否足够智能来移动而不是复制向量?或者我是否需要为 SimpleStruct 显式定义移动构造函数/赋值运算符才能利用向量移动?
Say I have a simple struct that contains a vector and defines a copy assignment operator, and a function that returns this struct, like so:
struct SimpleStruct
{
vector< int > vec1;
operator=( SimpleStruct& other )
{
vec1 = other.vec1;
}
}
SimpleStruct GetStruct();
As I understand it, because I've declared a copy assignment operator, the compiler won't automatically generate a move constructor for SimpleStruct.
So if I use the GetStruct
function like this:
SimpleStruct value = GetStruct();
Is the compiler smart enough to move rather than copy the vector when I say vec1 = other.vec1;
? Or will I need to explicitly define a move constructor/assignment operator for SimpleStruct to take advantage of a vector move?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在复制构造函数或复制赋值运算符中,复制意味着复制。该语言永远不会根据函数的调用方式对函数的内容进行任何上下文调整。
但是,
SimpleStruct value = GetStruct();
中可能不会发生任何复制,因为 复制省略适用。Inside a copy constructor or copy assignment operator, copy means copy. The language never makes any contextual adjustment to the contents of a function based on how it is called.
However, it's likely that no copy will occur in
SimpleStruct value = GetStruct();
because copy elision applies.C++11 对于何时允许发生移动有非常严格的规则。除非涉及临时变量,否则这些规则要求显式使用 std::move 或类似的转换(例如在某些情况下的 std::forward)。
是的,您可以移动一些东西。但这并不是偶然发生的。这一定是经过深思熟虑的。
另外,编写可以修改正在复制的内容的复制赋值运算符通常是粗鲁的。这就是为什么他们通常采用 const& ,这几乎保证了无法移动。
一般来说,这就是为什么您不显式定义复制和移动构造函数。让编译器完成它的工作并为您生成这些工作(除非您使用 VC++,它不执行移动构造函数/赋值的工作)。仅显式地为较低级别的容器编写复制/移动构造函数;任何更大的东西都应该依赖这些价值类型来完成它们的工作。
C++11 has very strict rules about when movement is allowed to happen. And unless a temporary is involved, those rules require the explicit use of
std::move
or a similar cast (such asstd::forward
in some cases).Yes, you could move something. But it wouldn't happen by accident; it would have to be deliberate.
Also, it is generally rude to write a copy-assignment operator that can modify what is being copied. That's why they usually take a
const&
, which pretty much guarantees the inability to move.In general, this is why you don't explicitly define copy and move constructors. Let the compiler do it's job and generate those for you (unless you're using VC++ which doesn't do its job for move constructors/assignment). Only explicitly write copy/move constructors for lower-level containers; anything larger should just rely on those value types to do their jobs.