我具有以下工厂功能:
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();
在return语句中,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();
真的需要吗?
答案 0 :(得分:12)
在return语句中,
vec
被认为是xvalue或prvalue,因此被移动或复制了吗?
vec
总是 一个左值。即使在简单的情况下:
std::vector<int> factory() {
std::vector<int> vec;
return vec;
}
即 still 返回左值。只是我们有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;
}