Search code examples
c++stlconstructorsetpredicate

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.


Solution

  • 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.