c++ - 诱导编译器避免/触发右值上的副本
问题描述
在下面的代码中,我有一个函数foo
以 a 作为参数,std::function
返回一个大对象(这里是 a vector
)并仅使用它来访问它的值。大对象可以作为主显示中的两个 lambda 表达式即时构建fun
或作为对现有对象的引用。
我想通过选择正确的返回类型来优化此代码以避免无用的副本std::function
。
如果我使用按值返回,RVO 会优化副本并为“即时构建”情况制作我想要的内容:没有完成副本,向量准确地构建在它需要的位置,然后在最后销毁的foo
。但是,在第二种情况下,即使我真的不需要它,编译器也会复制向量。第二种情况是按引用返回的完美情况,但这会破坏第一种情况,因为对临时的引用是邪恶的。
我知道foo
直接引用向量可以解决这种特殊情况下的问题,但我的用例更复杂。有没有办法解决这个问题?
#include <vector>
#include <iostream>
#include <functional>
struct myVec : public std::vector<double> {
using std::vector<double>::vector;
myVec(myVec const & v){
std::cout << "Copy ctor\n";
*this=v;
}
};
void foo(std::function<myVec(void)> fun){
for(auto & v : fun()){
std::cout << v << " ";
}
std::cout<<std::endl;
}
int main() {
foo([]()->myVec{return myVec(100,0.);});
myVec existing(100,1.);
foo([&existing]()->myVec{return existing;});
return 0;
}
解决方案
[&existing]()->myVec{return existing;}
通过副本返回,而不是通过引用返回,因此它会创建副本。
你需要这样[&existing]()->myVec&{return existing;}
。
然后问题是std::function
所以要么提供2个重载(void foo(std::function<myVec()>)
和void foo(std::function<myVec&()>)
),要么使用模板并摆脱std::function:
template <typename F>
void foo(F fun){
for (const auto & v : fun()){
std::cout << v << " ";
}
std::cout<<std::endl;
}
推荐阅读
- reactjs - 在 React 中,使用 TypeScript,我如何将道具转发给作为道具传递的组件?
- python-3.x - 如何从 Dataflow 批量(有效)发布到 Pub/Sub?
- wordpress - 带有数据的 img src:当我在 wordpress 的后台连接时,图像可以工作,并且在我没有连接时不会出现
- javascript - react-native-chart-kit - 在折线图的 y 轴上设置最大值
- spring - 我可以删除 Spring 日志文件吗?
- django - 如果我在模型选择领域有很多选择,这很糟糕吗?
- github - 需要多个组的 Github PR 批准
- business-objects - SAP Business objects XI:创建每个 id 具有多个值的类别
- python - 如何在不安装任何东西的情况下在另一台计算机上运行 Python 项目?
- javascript - 如何在 Visual Studio Code 中显示更多选项卡空间?(实际上没有增加缩进大小)