C 11:移动/复制结构模糊?

在C 11中,我们可以定义复制和移动构造函数,但是它们都允许在同一个类上?如果是这样,你如何消除他们的用法?例如:

Foo MoveAFoo() {
  Foo f;
  return f;
}

以上是副本吗?一个动作?我怎么知道?

通常不会因为RVO

如果无法执行该优化,那么这将是一个动作,因为被返回的对象超出了范围(并将在之后被销毁)。如果不能被移动,那么它将被复制。如果无法复制,将无法编译。

移动构造函数的整个一点是,当一个拷贝将要被一个即将被销毁的对象构成时,通常不需要做一个完整的拷贝,资源可以从垂死的对象移动到对象正在被创建。

根据要移动/复制的对象将要发生的事情,您可以知道复制或移动构造函数何时被调用。是要超出范围并被破坏吗?如果是这样,移动构造函数将被调用。如果没有,复制构造函数。

当然,这意味着你可以在同一个类中同时拥有一个移动构造函数和复制构造函数。您也可以拥有一个副本分配运算符和一个移动分配运算符。

更新:当移动构造函数/赋值运算符被调用时,与普通拷贝构造函数/赋值运算符的关系可能不清楚。如果我理解正确,如果对象使用xvalue(eXpiring值)初始化,则调用move构造函数。 §3.10.1的标准说

An xvalue (an “eXpiring” value) also refers to an object, usually near
the end of its lifetime (so that its resources may be moved, for
example). An xvalue is the result of certain kinds of expressions
involving rvalue references (8.3.2). [ Example: The result of calling
a function whose return type is an rvalue reference is an xvalue. —end
example ]

标准§5的开始时表示:

[ Note: An expression is an xvalue if it is:

  • the result of calling a
    function, whether implicitly or explicitly, whose return type is an
    rvalue reference to object type,
  • a cast to an rvalue reference to
    object type,
  • a class member access expression designating a
    non-static data member of non-reference type in which the object
    expression is an xvalue, or
  • a .* pointer-to-member expression in
    which the first operand is an xvalue and the second operand is a
    pointer to data member.

In general, the effect of this rule is that
named rvalue references are treated as lvalues and unnamed rvalue
references to objects are treated as xvalues; rvalue references to
functions are treated as lvalues whether named or not. —end note ]

例如,如果NRVO可以完成,就像这样:

void MoveAFoo(Foo* f) {
    new (f) Foo;
}

Foo myfoo; // pretend this isn't default constructed
MoveAFoo(&myfoo);

如果NRVO不能做,但是Foo是可移动的,那么你的例子有点像这样:

void MoveAFoo(Foo* fparam) {
    Foo f;

    new (fparam) Foo(std::move(f));
}

Foo f; // pretend this isn't being default constructed
MoveAFoo(&f);

如果它不能移动,但它可以被复制,那就是这样

void MoveAFoo(Foo* fparam) {
    Foo f;

    new (fparam) Foo((Foo&)f);
}

Foo f; // pretend this isn't default constructed
MoveAFoo(&f);
http://stackoverflow.com/questions/9152798/c11-move-copy-construction-ambiguity

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:C 11:移动/复制结构模糊?