error: request for member '..' in '..' , which is of non-class type

2.1k views Asked by At

I use an STL priority_queue and give a custom comparator class whose constructor takes in the pointer to the vector that stores the priorities, thus -

#include <iostream>
#include <queue>          // std::priority_queue
#include <vector>         // std::vector

using namespace std;

class CompareReachDist
{
    const vector<float> *reach_dists;
public:
    CompareReachDist(const vector<float> *input)
    {
        reach_dists = input;
    }

    bool operator() (const size_t &l, const size_t &r) const
    {
        return (reach_dists->at(l) > reach_dists->at(r));
    }
};

typedef priority_queue<size_t, vector<size_t>, CompareReachDist> pq;
vector<float> reach_dists;

int main()
{
    pq seeds(CompareReachDist(&reach_dists));
    bool isEmpty = seeds.empty();

  return 0;
}

However, on compiling I get the error:

error: request for member 'empty' in 'seeds', which is of non-class type 'pq(CompareReachDist&) {aka std::priority_queue<unsigned int std::vector<unsigned int>, CompareReachDist>(CompareReachDist&)}'

Where am I going wrong ?

1

There are 1 answers

11
StoryTeller - Unslander Monica On BEST ANSWER

This is a parsing issue. Let's break it apart:

CompareReachDist(&reach_dists)

You may think this creates a temporary CompareReachDist with the address of the static reach_dists. But in the context of the overall declaration it is interpreted as a reference to a CompareReachDist. Strange, but that is because, roughly speaking, the grammar of C++ favors function declarations to object declaration. The following

pq seeds(CompareReachDist(&reach_dists));

Is an overall declaration of a function. It accepts a CompareReachDist& and returns a pq.

The error you receive is because, quite obviously, a function doesn't have an empty member you can call.

The solution since C++11 is to favor list initialization, which breaks the ambiguity and its resolution as a function declaration. So you can do this:

pq seeds{CompareReachDist{&reach_dists}};

And get an object, as one would expect.