0

假设我在 C++ 中有这个构造函数:

 A::A( std::string const& name,
       std::string const& type,
       std::vector<B> const& b_vec,
       bool unique )
     : _name(name), _type(type), _b_vec(b_vec), _unique(unique)
     { };

我想在参数是右值的情况下重载这个构造函数(我想在那里使用移动语义)。

 A::A( std::string && name,
       std::string && type,
       std::vector<B> && b_vec,
       bool unique )
     : _name(name), _type(type), _b_vec(b_vec), _unique(unique)
     { };

当所有参数都是右值时,上面的工作正常,但假设如果只有其中一些是在下一个示例中:

 // create some lvalues somehow
 std::string name   = "stack overflow";
 std::vector<B> vec = { ... }; // implementation of B's constructot is not important

 // call a mixed constructor
 A new_A_instance(name, "cool-website", vec, true);

据我了解,由于 'const&' 不能绑定到 '&&' 但 '&&' 可以绑定到 'const&' 将使用第一个(非移动)构造函数。

这似乎不是最理想的,因为四个参数中的两个可以移动(因为它们是右值)而不是被复制(如第一个构造函数中的情况)。

因此,对于这种特定情况,我可以重载运算符,但可以轻松地想象其他参数是右值而其他参数是左值的情况。我应该为每种情况重载构造函数吗?随着参数数量的增加,这将组合导致非常多的重载......

我有点觉得有更好的解决方案(也许使用模板,但我的模板知识低得可耻)。

注意:这个问题与重载传递引用函数以移动函数本身无关,但我发现这是一个很好的例子(特别是因为重载感觉没有太大不同)。另请注意,我只是以构造函数为例,但重载函数可以是任何东西。

4

1 回答 1

2

按值传递,这就是移动语义的用途:

 A::A(std::string name, std::string type, std::vector<B> b_vec, bool unique )
   : _name(std::move(name)), _type(std::move(type)), _b_vec(std::move(b_vec)),
     _unique(unique)
 { };

这在每种情况下都有预期的行为。按值传递临时值允许编译器执行复制省略,它几乎总是这样做。

请注意,在您的第二个代码中,由于您不使用std::move. 请注意,当你写

void foo(bar&& x)
{
    ...
}

然后在 的体内foox是一个左值。有名字的对象总是左值。std::move(x)在此主体内,如果您打算x作为右值传递,则必须使用。

于 2012-09-23T20:00:03.867 回答