【问题标题】:build tuple using variadic templates使用可变参数模板构建元组
【发布时间】:2012-04-04 15:49:54
【问题描述】:

所以我有一些在 C++11 之前编写的代码,它根据模板参数解析字符串。我不想为每个数量的参数都定义一个定义,而是想使用可变参数模板,但我无法理解如何正确初始化元组。请参阅我想要的简化代码,这是针对 2 个参数的特殊情况:

template <typename Arg1, typename Arg2>
struct parser
{
  static tuple<Arg1, Arg2> parse(const string& str) 
  {
    Arg1 arg1;
    Arg2 arg2;
    // do the parsing with for example stringstream
    return tuple<Arg1, Arg2>(arg1, arg2);             
  }
};

在可变参数情况下将参数放入元组时遇到问题。我可以构造返回值持有者:

tuple<Args...> retVal; 

但我不知道是否有办法遍历参数并将它们放在一个元组中。我已经看到了一些递归魔法来获得例如 printf 函数,但我不知道它是否适用于这种情况。

【问题讨论】:

  • 您是否尝试根据字符串解析的结果更改元组的类型?
  • 可以在不使用递归的情况下遍历元组的所有元素,但代价是额外的函数调用。我已经多次描述了该技术(hereherehere)。 (在每种情况下,重要的部分都是indices。)

标签: c++ templates c++11


【解决方案1】:

您不需要辅助类。用函数来代替。

template <typename T> std::tuple<T> parse(std::istream& is) 
{
  T t; is >> t;
  return std::tuple<T>(std::move(t));
}

template <typename T, typename Arg, typename... Args>
std::tuple<T, Arg, Args...> parse(std::istream& is) 
{
  T t; is >> t;
  return std::tuple_cat(std::tuple<T>(std::move(t)),
                        parse<Arg, Args...>(is));
}

template <typename... Args>
std::tuple<Args...> parse(const std::string& str) 
{
  std::istringstream is(str);
  return parse<Args...>(is);
}

编辑:今天,我想到了如何使用扩展以非常简单的方式做到这一点:

template <typename T> T read(std::istream& is)
{
  T t; is >> t; return t;
}

template <typename... Args>
std::tuple<Args...> parse(std::istream& is) 
{
  return std::make_tuple(read<Args>(is)...);
}

template <typename... Args>
std::tuple<Args...> parse(const std::string& str) 
{
  std::istringstream is(str);
  return parse<Args...>(is);
}

【讨论】:

  • thanx,我不知道有tuple_cat这样的函数,太棒了!
  • @ipc 如果您使用 std::make_tuple(read(is)...),流的读取顺序似乎是未定义的。见stackoverflow.com/questions/14056000/…
  • @ErikSjölund:AFAIR 定义明确(参见第 8.5.4/4 节)。
  • @ipc 我想我需要购买 C++ 标准才能看到那段。在我的问题中,有人建议我使用 std::make_tuple {} 而不是 std::make_tuple() 以避免以未定义的顺序读取流。但我刚刚意识到您对 std::make_tuple 的使用与我的问题有所不同。你有一个函数read&lt;Args&gt;(is),但我有一个构造函数Args(is)。所以有点不一样。
  • @ErikSjölund:购买标准? n3337 工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
  • 2017-07-11
  • 2011-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多