c ++可变参数模板折叠表达式

时间:2018-02-20 07:55:13

标签: c++ templates

我正在阅读一本关于模板的书。这是一段使用折叠表达式的示例代码,使用运算符遍历二叉树中的路径 - > *:

// define binary tree structure and traverse helpers:
struct Node {
  int value;
  Node* left;
  Node* right;
  Node(int i=0) : value(i), left(nullptr), right(nullptr) {
  }
  //...
};
auto left = &Node::left;
auto right = &Node::right;

// traverse tree, using fold expression:
template<typename T, typename... TP>
Node* traverse (T np, TP... paths) {
  return (np ->* ... ->* paths);      // np ->* paths1 ->* paths2 ...
}

int main()
{
  // init binary tree structure:
  Node* root = new Node{0};
  root->left = new Node{1};
  root->left->right = new Node{2};
  //...
  // traverse binary tree:
  Node* node = traverse(root, left, right);
  //...
}

我不太明白这条线

auto left = &Node::left;
auto right = &Node::right;

因为我以前认为::运算符应用于类只会引用它的静态成员,也许我在这种情况下错了,我知道::是作用域解析运算符,它可能会引用Node的左边即使它不是静止的,但为什么它可以使用&amp;运营商得到它的地址?实际上,我在考虑的是,这只是一个别名,如

using left = &Node::left; // can't compile

仅在

时才有效
auto left = &Node::left;

汽车的结果是什么?这个表达式的显式类型?

请注意:此处使用全局左侧和右侧

Node* node = traverse(root, left, right);

这是main中的最后一行。

我试图运行它,一切正常,但我不太明白,它是如何工作的?

1 个答案:

答案 0 :(得分:3)

leftright的类型是

Node* Node::*left

pointer to class data member的案例。您可以想象它在left的未指定实例的表示中编码Node 的偏移量,而不是内存中的固定位置。只有在提供此实例时才能取消引用它,

node.*left

(给出Node*)或在你的情况下,根是(正常)指针本身,

root->*left.

这就是行

return (np ->* ... ->* paths);

展开。