返回保留引用但复制r值的元组

问题描述 投票:0回答:1

我需要制作一个lambda,该lambda返回一个元组,用于对对象向量进行排序。元组从对象中收集属性的集合。一些属性是对不应复制的大对象的引用(下面的代码中的f()),其他属性是较小的r值(下面的代码中的g())。编写lambda的最简单或最惯用的方法是什么?

#include <vector>
#include <tuple>
#include <algorithm>

struct A {
    std::vector<int> const &f() const;
    int g() const;
};

void example() {
    auto sort_key = [](A const &a) {
        //return std::tuple{a.f(), a.g()}; // copies the vector from f()
        //return std::tie(a.f(), a.g()); // can't bind the int from g()
        //return std::forward_as_tuple(a.f(), a.g()); // returns a reference to the int from g(), which expires when this function returns
        return std::tuple<std::vector<int> const &, int>{a.f(), a.g()}; // works, but requires specifying the types
    };

    std::vector<A> v;
    std::sort(v.begin(), v.end(), [&](A const &a, A const &b) {
        return sort_key(a) < sort_key(b);
    });
}

我很尴尬地说forward_as_tuple是我的第一次尝试,经过长时间的调试会话后,我意识到它正在为第二个属性返回int &&,该值超出范围。用这种方式写是肌肉记忆,因为据我的理解,forward_as_tuple(...) < forward_as_tuple(...)非常好:由于所有内容都在一行代码中,因此我们可以延长所有引用的生命周期。

在构造元组时明确指定类型-第一属性的引用,第二属性的值,这就是我现在正在做的事情,但是我更喜欢清洁的东西。 (好吧,事实是这还不错,但是我问是因为我很好奇是否有更好的东西。)

我可能可以建立一个辅助函数,将其称为forward_references_but_copy_rvalues,但是标准库中已经可以执行此操作?

c++ tuples idioms rvalue
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.