首页 > 解决方案 > 如何从对象 std::tuple 获取对元组尾部的引用

问题描述

我已经定义:

template<class Head,class ...Tail>
struct elem{
    std::tuple<Head,Tail...> dm;
};

我有用于类 elem 的函数 head()、tail() 和其他函数,但它们创建副本,它们返回元组头部或元组尾部的副本,但我需要引用 this-> DM。

因为头很容易,std::get<0>(this->dm)给我参考。

尾巴可以吗?尾部是指第一个元素之后的所有元素。

标签: c++tuplesc++17

解决方案


tuple<A, B, C>只有当 a在内部存储为与 cons 单元等效的东西时,这样的事情才有可能:

struct __tuple_A_B_C {
    A car;
    tuple<B, C> cdr;

    A& head() { return car; }
    tuple<B, C>& tail() { return cdr; }
};

但事实并非如此——你所知道的只是你有类型AB和的子对象C。它们的布局是完全未指定的——你肯定不知道实现是否使用像这样的递归来实现tuple。他们被允许,但我不确定是否有人这样做。

你能做的最好的事情是,给定一个tuple<A, B, C>回报 a tuple<B&, C&>。在 C++17 中,实现起来还不错:

template<class Head,class ...Tail>
struct elem{
    std::tuple<Head,Tail...> dm;

    auto tail() {
        return std::apply([](auto&, auto&... rest){
            return std::tie(rest...);
        }, dm);
    }
};

但是如果你真的想要这种递归的 cons-cell-like 方法,你可能最好实际实现自己的递归,这样你就可以获得所需的行为:

template <class Head, class... Tail>
struct elem {
    Head head;
    elem<Tail...> tail;
};

template <class Head>
struct elem<Head> {
    Head head;
};

取决于你实际在做什么。


推荐阅读