【发布时间】:2021-02-08 22:51:16
【问题描述】:
我有以下工厂函数:
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();
真的需要吗?
【问题讨论】:
-
你必须做
return { true, std::move(vec) };。 -
是的,这里需要这样做以确保矢量将被移动。但是编译器大多足够聪明,可以优化副本
-
@bartop:编译器不允许“优化掉副本”。
-
@NicolBolas 实际上,只要可观察的行为没有改变,他们就可以做任何事情。会创建一个可观察的副本(前提是构造函数或析构函数中没有可观察到的副作用)?
-
@Aconcagua:是的,因为
allocator::construct/destruct和vector元素的复制构造函数都是可观察到的副作用。
标签: c++ c++17 move-semantics