5

i m reading a book about templates.there's a piece of sample code using a fold expression to traverse a path in a binary tree using operator ->*:

// 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);
  //...
}

i dont quite understand the line

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

as i used to think the :: operator apply to classes will only refer to its static member,maybe i'm wrong in this case,and i do know :: is scope resolution operator, it may refer to Node's left anyway even its not static , but why can it use & operator to get its address? actually, what i was considering, is this just an alias like

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

only work if

auto left = &Node::left;

what's the result of auto? the explicit type of this expression?

note that: the global left and right are used here

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

which is the last line in main.

i 've tried to run it , it all works, but i don't quite get it,how does it work?

May
  • 101
  • 7

1 Answers1

7

The type of left and right is

Node* Node::*left

a case of pointer to class data member. You can imagine it encodes the offset of left within the representation of an unspecified instance of Node, rather than a fixed position in memory. It can only be dereferenced when this instance is provided,

node.*left

(giving a Node*) or in your case, where the root is a (normal) pointer itself,

root->*left.

This is what the line

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

unfolds to.

The Vee
  • 11,420
  • 5
  • 27
  • 60