I'm writing a library to run certain algorithms on tree-like objects. I have an `edge_t`

class that has `const unsigned int`

data members `edge_id`

and `weight`

that serve, respectively, as the `edge_t`

's unique identifier and the weight of the edge.

I have written `tree_t`

and `subtree_t`

classes in C++, both of which contain maps to pointers to `edge_t`

s. Both `tree_t`

and `subtree_t`

are each derived from an abstract `basic_tree_t`

class that contains all the functionality that tree-like objects are supposed to have, including the following methods:

```
// returns the sum of the weights of the edge_ts below the edge_t pointed to by edge_ptr
unsigned int basic_tree_t::weight(const edge_ptr) const
// returns the number of edge_ts below the edge_t pointed to by edge_ptr
unsigned int basic_tree_t::num_descendents(const edge_ptr) const
```

I'm writing some other code in which the user inputs a `tree_t`

object, and the code has to iteratively sample a `subtree_t`

from it, do some calculation, sample another `subtree_t`

, do more calculation, and so on. To do the calculation the code needs to know the values of `weight`

and `num_descendents`

for every edge in each of these subtree.

To avoid calculating the same values repeatedly, each time I build a new subtree I'm creating `std::map<unsigned int, unsigned int> weight_map`

and `std::map<unsigned int, unsigned int> num_descendents_map`

, which map each `edge_id`

of the subtree's edges to the values output by the respective member functions in `basic_tree_t`

and then work with those. I wrote the following functions to populate these maps:

```
void populate_weight_map(subtree_t & S, edge_ptr & e, std::map<unsigned int, unsigned int> & weight_map)
{
weight_map.insert(std::pair<unsigned int, unsigned int>(e->edge_id, S.weight(e)));
for (auto & c : *(e->children))
if (S.contains(c))
populate_weight_map(S, c, weight_map);
}
void populate_num_descendents_map(subtree_t & S, edge_ptr & e, std::map<unsigned int, unsigned int> & num_descendents_map)
{
num_descendents_map.insert(std::pair<unsigned int, unsigned int>(e->edge_id, S.num_descendents(e)));
for (auto & c : *(e->children))
if (S.contains(c))
populate_weight_map(S, c, num_descendents_map);
}
```

Those are largely the same function, so I thought it would make more sense to write one function that takes a pointer to the relevant `basic_tree_t`

member function as a fourth argument, something like this:

```
void populate_map(subtree_t & S, edge_ptr & e, std::map<unsigned int, unsigned int> & m, unsigned int (basic_tree_t::*f)(const edge_ptr) const)
{
m.insert(std::pair<unsigned int, unsigned int>(e->edge_id, (S.*f)(e)));
for (auto & c : *(e->children))
if (S.contains(c))
populate_map(S, c, m, &basic_tree_t::*f); // ERROR ON THIS LINE!
}
```

但是，编译器在最后一行返回不透明错误：

```
error: expected unqualified-id
populate_map(S, c, m, &basic_tree_t::*f);
^
```

What should the fourth argument to `populate map`

be?