c++ - 返回 std::tuple 并移动语义/复制省略
问题描述
我有以下工厂功能:
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
orprvalue
并因此被移动或复制省略了?
我的猜测是否定的,因为编译器std::tuple
在对 return 语句中的 进行列表初始化时,仍然不知道 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;
}
那仍然返回一个左值。只是我们有特殊的规则说,在这种情况下,当我们返回自动对象的名称时,我们只是忽略副本(以及在复制省略不适用的情况下的另一个特殊规则,但我们仍然尝试从左值移动)。
但是那些特殊规则只适用于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;
}
推荐阅读
- typescript - 有没有一种方法可以键入一个函数,该函数通过名称从 Typescript 中的对象中删除属性,同时保持类型安全(不进行类型转换)?
- react-native - 使用 React Native 上的样式化组件级联文本颜色
- c# - C#属性检查是一个值等于构造函数参数并获取构造函数值
- reporting-services - 在 Microsoft Visual Studio IDE 中生成 SSRS 项目时,我在哪里可以找到并设置 .rdl 文件的报告名称?
- reactjs - 如何将元标记包含到必须等待 API 调用的 React SSR 路由?
- python - 哥德巴赫猜想在 Python 中最多验证 N
- jenkins - 如何在 Jenkins 中配置代理以访问 Git 存储库?
- java - Java Prim 算法实现
- visual-studio-code - Visual Studio Code 使用一小时后占用了 10.7 GB RAM
- python - 如何将 flask-sqlalchemy 与 Google Cloud Functions 一起使用?