return 的值什么时候可以?
When is return by value ok?
我仍然不太确定 return-by-value 在 C++ 中什么时候是个好主意,什么时候不是。在下面的情况下,可以吗?
vector<int> to_vec(const Eigen::MatrixXi& in){
vector<int> out;
// copy contents of in into out
return out;
}
Eigen::MatrixXi to_eigen(const vector<int>& in){
Eigen::MatrixXi out;
// copy contents of in into out
return out
}
根据这些对象 vector
和 MatrixXi
的实际工作方式,它可能会产生昂贵的副本。另一方面,我假设他们利用 C++ 的 move 功能通过重用底层数据以低成本复制。
在不完全了解实现的情况下,我可以假设什么?
关于 C++ 中 return 值的 Thumb 规则是:
- 从不return 对局部变量的引用
- 从不 return 指向局部变量的指针
- 不要return使用移动语义的命名值
至于 (3) - 这是 C++ 的一个已知问题 - 我们都知道,当一个对象 return 是值时 - 它会激活复制构造函数。这理论上是正确的,但实际上是错误的。启用优化后,编译器将在对象上使用 复制省略。
copy elision 是一种优化技术,它使值在调用者范围内而不是在被调用者范围内创建,从而防止昂贵的复制。对该对象的修改将发生在被调用者范围内。
至于 (1) 和 (2),还有一个关于协程和生成器的极端情况,但除非你知道你正在处理它们,否则 (1) 和 (2) 始终有效。
在声明局部变量、初始化它并按值 return 处理它的情况下,您可以非常安全地假设您的编译器将 elide 副本。
这种情况被称为命名return价值优化。本质上,不是在函数调用中分配 return 值,而是在调用站点完成并作为引用传入。按值返回是这里最好的选择,因为你不需要在调用点声明一个变量来传递,但性能会和你一样。
在 C++17 中,copy elision will be mandatory 在大多数情况下涉及纯右值(例如 T t = get_t();
或 return get_t()
),但对于 NRVO 仍然是可选的。
我仍然不太确定 return-by-value 在 C++ 中什么时候是个好主意,什么时候不是。在下面的情况下,可以吗?
vector<int> to_vec(const Eigen::MatrixXi& in){
vector<int> out;
// copy contents of in into out
return out;
}
Eigen::MatrixXi to_eigen(const vector<int>& in){
Eigen::MatrixXi out;
// copy contents of in into out
return out
}
根据这些对象 vector
和 MatrixXi
的实际工作方式,它可能会产生昂贵的副本。另一方面,我假设他们利用 C++ 的 move 功能通过重用底层数据以低成本复制。
在不完全了解实现的情况下,我可以假设什么?
关于 C++ 中 return 值的 Thumb 规则是:
- 从不return 对局部变量的引用
- 从不 return 指向局部变量的指针
- 不要return使用移动语义的命名值
至于 (3) - 这是 C++ 的一个已知问题 - 我们都知道,当一个对象 return 是值时 - 它会激活复制构造函数。这理论上是正确的,但实际上是错误的。启用优化后,编译器将在对象上使用 复制省略。
copy elision 是一种优化技术,它使值在调用者范围内而不是在被调用者范围内创建,从而防止昂贵的复制。对该对象的修改将发生在被调用者范围内。
至于 (1) 和 (2),还有一个关于协程和生成器的极端情况,但除非你知道你正在处理它们,否则 (1) 和 (2) 始终有效。
在声明局部变量、初始化它并按值 return 处理它的情况下,您可以非常安全地假设您的编译器将 elide 副本。
这种情况被称为命名return价值优化。本质上,不是在函数调用中分配 return 值,而是在调用站点完成并作为引用传入。按值返回是这里最好的选择,因为你不需要在调用点声明一个变量来传递,但性能会和你一样。
在 C++17 中,copy elision will be mandatory 在大多数情况下涉及纯右值(例如 T t = get_t();
或 return get_t()
),但对于 NRVO 仍然是可选的。