在C++ 0x中传递/移动构造函数的参数

Opt*_*Opt 25 c++ rvalue-reference move-constructor c++11

如果我有一个带有n个参数的构造函数,那么任何参数都可以是rvalue和lvalue.是否可以通过为rvalues移动语义来支持这一点,而无需为每个可能的rvalue/lvalue组合编写2 ^ n个构造函数?

GMa*_*ckG 31

你按每个值取值,如下:

struct foo
{
    foo(std::string s, bar b, qux q) :
    mS(std::move(s)),
    mB(std::move(b)),
    mQ(std::move(q))
    {}

    std::string mS;
    bar mB;
    qux mQ;
};
Run Code Online (Sandbox Code Playgroud)

参数初始化函数参数将是复制构造函数或移动构造函数.从那里,您只需将函数参数值移动到您的成员变量中.

请记住:复制和移动语义是由类提供的服务,而不是由您提供的服务.在C++ 0x中,您不再需要担心如何获取自己的数据"副本"; 只要求它,让课程做到:

foo f("temporary string is never copied", bar(), quz()); // no copies, only moves
foo ff(f.mS, f.mB, f.mQ); // copies needed, will copy
foo fff("another temp", f.mB, f.mQ); // move string, copy others
Run Code Online (Sandbox Code Playgroud)

注意:您的构造函数只接受值,这些值将弄清楚如何构造自己.当然,从那里开始,您可以将它们移动到您想要的位置.

这无处不在.有一个需要副本的功能吗?在参数列表中进行:

void mutates_copy(std::string s)
{
    s[0] = 'A'; // modify copy
}

mutates_copy("no copies, only moves!");

std::string myValue = "don't modify me";
mutates_copy(myValue); // makes copy as needed
mutates_copy(std::move(myValue)); // move it, i'm done with it
Run Code Online (Sandbox Code Playgroud)

在C++ 03中,你可以很好地模拟它,但它并不常见(根据我的经验):

struct foo
{
    foo(std::string s, bar b, qux q)
    // have to pay for default construction
    {
        using std::swap; // swaps should be cheap in any sane program

        swap(s, mS); // this is effectively what
        swap(b, mB); // move-constructors do now,
        swap(q, mQ); // so a reasonable emulation
    }

    std::string mS;
    bar mB;
    qux mQ;
};
Run Code Online (Sandbox Code Playgroud)

  • @Gene:但是,你没有处理rvalues.您可能已将rvalues传递给foo构造函数.那些将被移动到左值s,b和q中.在您的版本中,您可以直接使用s来构造mS.s是*不是一个右值,因此不会出现省略或移动构造.你可以用嘈杂的构造函数来演示它.http://ideone.com/CRbaA (3认同)
  • +1很棒,在新的世界里,你只需要按价值看待你的论点,一切都会尽可能好.那好极了.您可以添加赋值运算符以获得乐趣吗? (2认同)
  • @Kerrek:如果您需要参数的副本,则取值,但如果您只需要检查它们(常量引用)或修改它们(引用),则不需要。我相信您可能知道这一点,但阅读您评论的人可能不知道。 (2认同)