【问题标题】:Using variadic templates to implement Get(Tuple) got "parameter packs not expanded with ‘...’" error使用可变参数模板实现 Get(Tuple) 得到“参数包没有用‘...’扩展”错误
【发布时间】:2013-04-12 03:28:09
【问题描述】:

我想实现类似 std::get(std::tuple) 的东西,有一个元组类:

template<typename ... Types> class Tuple;
template<> class Tuple<> {};
template<typename First, typename ... Rest>
class Tuple<First, Rest...>: private Tuple<Rest...> {
  First Member;
 public:
  Tuple(const First& first, const Rest& ... rest):
      Tuple<Rest...>(rest...), Member(first) {}

  const First& Head() const {
    return Member;
  }

  const Tuple<Rest...>& Tail() const {
    return *this;
  }
};

我还实现了一个辅助结构 tuple_element。

template<size_t I, class T>
struct tuple_element;

template<size_t I, class Head, class ... Tail>
struct tuple_element<I, Tuple<Head, Tail...> >:
    tuple_element<I - 1, Tuple<Tail...> > {};

template<class Head, class ... Tail>
struct tuple_element<0, Tuple<Head, Tail...> > {
  typedef Head type;
};

但我不知道如何实现 Get(Tuple) 函数。我想我什么都试过了。 我的最后一次尝试:

template<class T, class Head, class ... Tail>
T Get(size_t pos, const Tuple<Head, Tail...>& t) {
  if (pos > 0) {
    return Get<T>(pos - 1, t.Tail());
  }
  return t.Head();
}
template<size_t Pos, class Head, class ... Tail>
typename tuple_element<Pos, Tuple<Head, Tail...> >::type
    Get(const Tuple<Head, Tail...>& t) {
  return Get<typename tuple_element<Pos, Tuple<Head, Tail...> >::type>(Pos, t);
}

但我得到一个错误:参数包没有用“...”扩展

我做错了什么?

【问题讨论】:

  • Get&lt;T&gt;(pos - 1, t.Tail()); - Tail 是这里的一个类型,它不起作用。
  • 非常感谢!我现在很开心!
  • 您需要使用enable_if 或模板特化。第一个 Get 函数根据运行时条件返回 THead - 这是不可能的。

标签: c++ templates variadic-templates


【解决方案1】:

就是这样。我已经使用模板专业化实现了它,但是由于功能部分专业化的残疾,我修改了上面的 tuple_element 结构。这就是我终于拥有的:

template<size_t I, class T>
struct TupleElement;

template<size_t I, class Head, class ... Rest>
struct TupleElement<I, Tuple<Head, Rest...> >:
    public TupleElement<I - 1, Tuple<Rest...> > {
  static typename TupleElement<I, Tuple<Head, Rest...> >::Type
      Get(const Tuple<Head, Rest...>& t) {
    return TupleElement<I - 1, Tuple<Rest...> >::Get(t.Tail());
  }
};

template<class Head, class ... Rest>
struct TupleElement<0, Tuple<Head, Rest...> > {
  typedef Head Type;
  static typename TupleElement<0, Tuple<Head, Rest...> >::Type
      Get(const Tuple<Head, Rest...>& t) {
    return t.Head();
  }
};

template<size_t Pos, class Head, class ... Rest>
typename TupleElement<Pos, Tuple<Head, Rest...> >::Type
    Get(const Tuple<Head, Rest...>& t) {
  return TupleElement<Pos, Tuple<Head, Rest...> >::Get(t);
}

感谢大家提供有用的建议。

【讨论】:

    猜你喜欢
    • 2014-04-29
    • 1970-01-01
    • 2014-10-30
    • 2015-05-21
    • 1970-01-01
    • 1970-01-01
    • 2011-10-19
    相关资源
    最近更新 更多