相当印刷元组的解剖学

5 c++ tuples pretty-print variadic-templates c++11

不久前,打印出std :: tuple的解决方案发布在这里.在大多数情况下,我得到了正在发生的事情.我无法理解print_tuple函数中发生的事情.

template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch,Tr>& os, Tuple const& t, seq<Is...>){
  using swallow = int[];
  (void)swallow{0, (void(os << (Is == 0? "" : ", ") << std::get<Is>(t)), 0)...};
}
Run Code Online (Sandbox Code Playgroud)

我不知道这个函数体内发生了什么.据我所知,它与拆包有关Is.我得到了条件,Is == 0正在检查我们是否处于头部元素.

发生什么了?

Bar*_*rry 8

让我们来看一个带有任意元组的例子,说:

using Tuple = tuple<char, int, string>;
Run Code Online (Sandbox Code Playgroud)

因此,我们的函数将被调用的整数序列是:

seq<0, 1, 2>
Run Code Online (Sandbox Code Playgroud)

我们的身体包装扩展是:

(void)swallow{0, (void(os << (Is == 0? "" : ", ") << std::get<Is>(t)), 0)...};
Run Code Online (Sandbox Code Playgroud)

如果我们按照编译器的方式手动扩展它,它会变成:

(void)swallow{0,
              (void(os << (0 == 0? "" : ", ") << std::get<0>(t)), 0),
              (void(os << (1 == 0? "" : ", ") << std::get<1>(t)), 0),
              (void(os << (2 == 0? "" : ", ") << std::get<2>(t)), 0)
              };
Run Code Online (Sandbox Code Playgroud)

然后评估分支:

(void)swallow{0,
              (void(os << "" << std::get<0>(t)), 0),
              (void(os << ", " << std::get<1>(t)), 0),
              (void(os << ", " << std::get<2>(t)), 0)
              };
Run Code Online (Sandbox Code Playgroud)

也就是说,我们正在构造一个4 0秒的整数数组,其副作用是打印出元组的内容,以逗号分隔,确保我们不会以额外的逗号开头.必须按顺序评估四个表达式,以确保按顺序打印元组内容.

初始转换(void)就是为了避免编译器在打开所有警告时应该发出的未使用变量警告.初始0在阵列初始化处理,其中该元组是空的情况.