c++ - 诱导编译器避免/触发右值复制

标签 c++ optimization copy

在下面的代码中,我有一个函数 foostd::function 作为参数返回一个大对象(这里是一个 vector)并仅使用它来访问其值。大对象可以由 fun 即时构建,也可以是对现有对象的引用,如主要节目中的两个 lambda 表达式。

我想通过选择 std::function 的正确返回类型来优化此代码以避免无用的拷贝。

如果我使用按值返回,RVO 优化拷贝并为“即时构建”情况制作我想要的:没有完成任何拷贝, vector 在它需要的地方准确构建,然后销毁在 foo 的末尾。但是,在第二种情况下,即使我真的不需要它,编译器也会复制 vector 。第二种情况是通过引用返回的完美情况,但这会破坏第一种情况,因为引用临时是邪恶的。

我知道让 foo 直接引用 vector 可以解决这个特殊情况下的问题,但我的用例更复杂。有办法解决吗?

#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;
}

关于c++ - 诱导编译器避免/触发右值复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57300190/

相关文章:

c++ - 如何改进 vector 搜索功能?

c++ - LibSSH C++ 包装器 - 离开范围时的基本远程连接段错误

c++ - 引用特定函数参数

C++:未使用的参数优化程度如何?

batch-file - 批处理 : Copy files where include and exclude conditions are met

c++ - 编写深拷贝 - 复制指针值

c++ - 移位语法错误

windows - Windows批处理文件街机游戏的优化

java - 仅使用乘法+移位(32 位)进行乘法+除法

bash - 如何复制带有符号链接(symbolic link)的目录并解决它们?