Tar*_*ani 10 c++ move-semantics c++17
我有以下工厂功能:
auto factory() -> std::tuple<bool, std::vector<int>>
{
std::vector<int> vec;
vec.push_back(1);
vec.push_back(2);
return { true, vec };
}
auto [b, vec] = factory();
Run Code Online (Sandbox Code Playgroud)
在退货声明被vec认为是xvalue或prvalue因此移动或复制被删除?
我的猜测是否定的,因为编译器std::tuple在return语句中进行列表初始化时仍然不知道vec将被销毁.所以也许需要一个明确的std :: move:
auto factory() -> std::tuple<bool, std::vector<int>>
{
...
return { true, std::move(vec) };
}
auto [b, vec] = factory();
Run Code Online (Sandbox Code Playgroud)
这真的需要吗?
Bar*_*rry 14
在return语句中被
vec视为xvalue或prvalue,因此移动或复制是否被删除?
vec是总是一个左值.即使在简单的情况下:
std::vector<int> factory() {
std::vector<int> vec;
return vec;
}
Run Code Online (Sandbox Code Playgroud)
那仍然是一个左值.只是我们有一些特殊的规则,说我们在这种情况下只是在我们返回自动对象的名称时忽略副本(在复制省略不适用的情况下另一个特殊规则,但我们仍然试图从左右移动).
但这些特殊规则仅适用于return object;案件,它们不适用于return {1, object};案件,无论它看起来多么相似.在你的代码中,这会做一个副本,因为这就是你要求的.如果你想搬家,你必须做:
return {1, std::move(object)};
Run Code Online (Sandbox Code Playgroud)
为了避免搬家,你必须做到:
auto factory() -> std::tuple<bool, std::vector<int>>
{
std::tuple<bool, std::vector<int>> t;
auto& [b, vec] = t;
b = true;
vec.push_back(1);
vec.push_back(2);
return t;
}
Run Code Online (Sandbox Code Playgroud)