假设我在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)
{ };
我想在参数为rvalues的情况下重载此构造函数(我想在那里使用移动语义)。
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)
{ };
当所有参数都是rvalues时,上面的一个工作正常,但是假设在下一个例子中只有其中一些是:
// 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&amp;'无法绑定到'&amp;&amp;'但是'&amp;&amp;'可以绑定到'const&amp;'将使用第一个(非移动)构造函数。
这似乎是次优的,因为可以移动四个参数中的两个(因为它们是rvalue)而不是被复制(如第一个构造函数中的情况)。
所以我可以为这个特定情况重载运算符,但是可以很容易地对其他参数是rvalue而其他参数是agin lvalue的情况进行成像。我应该为每种情况重载构造函数吗?随着参数数量的增加,这将导致非常多的重载......
我有点感觉有一个更好的解决方案(可能使用模板,但我的模板知识非常低)。
注意:这个问题与重载pass-by-ref函数并不依赖于移动函数本身,但我发现这是一个很好的例子(特别是因为重载不会感觉非常不同)。另请注意,我只使用构造函数作为示例,但重载函数可以是任何东西。
答案 0 :(得分: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)
{ };
这在每种情况下都有预期的行为。通过临时值传递允许编译器执行 copy elision ,这几乎总是如此。
请注意,在您的第二个代码中,由于您未使用std::move
,因此会进行复制。写的时候请注意
void foo(bar&& x)
{
...
}
然后在foo
的正文中,x
是左值。名称对象总是左值。在此正文中,如果您打算将std::move(x)
作为右值传递,则必须使用x
。