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