何时按值返回OK
When is return by value ok?
我仍然不确定当by-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 的s 移动功能来廉价地通过重复使用基础数据来复制。
在不完全知道实现的情况下,我可以假设什么?
在这种情况下,您要声明局部变量,对其进行初始化并按值返回,因此假设您的编译器会弹出副本,则可以非常安全。
此情况称为命名返回值优化。从本质上讲,它不会在函数调用中分配返回值,而是在呼叫站点上完成并作为参考通过。按值返回是这里的最佳选择,因为您无需在呼叫站点上声明一个变量即可传递,但是性能将好像您有。
在C 17中,在大多数情况下,副本将是强制性的(例如T t = get_t();
或return get_t()
),但对于NRVO仍然是可选的。
有关C 中返回值的拇指规则为:
- 永远不要返回对本地变量的引用
- 永远不要将指针返回到本地变量
- 不要使用移动语义返回命名值
至于(3) - 这是C 的已知问题 - 我们都知道,当对象按值返回时 - 它会激活复制构造函数。这是理论上 true,但实际上是错误。当打开优化时,编译器将在对象上使用在对象上复制Elision 。
复制ELISION 是一种优化技术,可以在呼叫者范围内而不是在Callee范围内创建该值,从而防止昂贵的副本。该对象的修改将发生在Callee范围中。
至于(1)和(2),也有一个有关Coroutines和Generator的角案,但是除非您知道您正在与它们打交道,否则(1)和(2)始终有效。
相关文章:
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- 什么时候在C++中返回常量引用是个好主意
- 你能重载对象变量名本身返回的内容吗
- 为什么 Serial.println(<char[]>);返回随机字符?
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- 如何获取std::result_of函数的返回类型
- QueryWorkingSet总是返回false
- (C++)分析树以计算返回错误值的简单算术表达式
- 访问者访问变体并返回不同类型时出错
- 如何返回一个类的两个对象相加的结果
- OpenInventor从9.8升级到10.4.2后,GLSL纹理返回零
- lower_bound()返回最后一个元素
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 奇怪的(对我来说)返回声明 - 在谷歌上找不到任何关于它的信息
- 如何取消对nullptr的屏蔽,返回正确的对象
- 何时按值返回OK
- 当坏ip提供给CURLOPT_DNS_SERVERS时,Curl返回all ok
- 只写对象的链接操作符= - OK返回rhs而不是*this
- 从内存效率的角度来看,在c++ 11中返回一个字符串OK
- 为什么getpeername()返回OK,结果却不是预期的