【问题标题】:How to get a reference to the tail of a tuple from an object std::tuple<Head,Tail...>如何从对象 std::tuple<Head,Tail...> 获取对元组尾部的引用
【发布时间】:2019-03-16 12:16:57
【问题描述】:

我已经定义了:

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

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

头部很简单,std::get&lt;0&gt;(this-&gt;dm)给我参考。

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

【问题讨论】:

  • “tail”是指tuple的最后一个元素吗?
  • 请定义“对尾部的引用”。
  • 不,我的意思是如果列表是 {0,1,2,3},那么尾部是 {1,2,3}。想法是 get(dm),get(dm),...,get(dm),但是将总数作为元组的引用。
  • C++ 不是 Prolog:“尾巴”不是 std::tuple。或者,如果是,则在特定于编译器的实现细节中。
  • 我写了 get(dm),但是如果我考虑元组 dm 的其余部分(没有 head==get(dm)),我将此提醒命名为尾巴,我需要一个尾巴的引用才能写在这个尾巴里。

标签: c++ tuples c++17


【解决方案1】:

只有当 tuple&lt;A, B, C&gt; 在内部存储为相当于 cons 单元格的东西时,这样的事情才可能发生:

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

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

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

您能做的最好的事情是,给定 tuple&lt;A, B, C&gt; 返回 tuple&lt;B&amp;, C&amp;&gt;。在 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;
};

取决于你实际在做什么。

【讨论】:

  • 谢谢,我怀疑你说了什么。
猜你喜欢
  • 2013-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-25
  • 2019-10-07
  • 1970-01-01
相关资源
最近更新 更多