Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I construct std::set with an instantiation of a predicate, but I can assign a std::set constructed that way?

So I've got an array (0 - n), holding values that I want std::set to use for its sorting. The array is unsigned int cost[n].

I'm using the following functor for this sorting:

struct ProxySorter {
  ProxySorter(const unsigned* arr) : proxy_array(arr) {}
  bool operator()(const unsigned& a, const unsigned& b) const {
    return proxy_array[a] < proxy_array[b];
  }
  const unsigned* proxy_array;
};

So here's the problem... When I construct the set, this is legal:

std::set<unsigned, ProxySorter> node_queue = std::set<unsigned, ProxySorter>(ProxySorter(cost));

I get no errors, and everything works as expected. But this seems hacked and sloppy.

However, this is apparently illegal:

std::set<unsigned, ProxySorter> node_queue(ProxySorter(cost));

Trying to just construct it with the ProxySorter(cost) causes a bunch of errors, saying stuff like this for every set member call:

error: request for member erase in node_queue, which is of non-class type std::set<unsigned int, ProxySorter>(ProxySorter)

What is the problem with the regular construction? Why does the assignment work? What's the difference here that I'm missing? Any help greatly appreciated, thanks.

Oh and sorry about the title of the question, I wasn't really sure what to call this.

like image 606
Robert Kelly Avatar asked Nov 21 '11 03:11

Robert Kelly


1 Answers

Most-vexing-parse. You need another pair of parentheses:

std::set<unsigned, ProxySorter> node_queue((ProxySorter(cost)));

Else it will be interpreted as the declaration of a function returning your set type and taking an argument of type ProxySorter named cost.

like image 144
Xeo Avatar answered Oct 29 '22 12:10

Xeo