1

Possible Duplicate:
Can inner classes access private variables?

So I'm trying to use a priority queue, and in the context of this queue I want to define an integer i to be "less" than another integer j if D[i] < D[j]. How can I do this? (D is a data member of an object)

So far I have

/* This function gets the k nearest neighbors for a user in feature
 * space.  These neighbors are stored in a priority queue and then
 * transferred to the array N. */
void kNN::getNN() {
    int r;
    priority_queue<int, vector<int>, CompareDist> NN;

    /* Initialize priority queue */
    for (r = 0; r < k; r++) {
        NN.push(r);
    }

    /* Look at the furthest of the k users.  If current user is closer,
     * replace the furthest with the current user. */
    for (r = k; r < NUM_USERS; r++) {
        if (NN.top() > r) {
            NN.pop();
            NN.push(r);
        }
    }

    /* Transfer neighbors to an array. */
    for (r = 0; r < k; r++) {
        N[r] = NN.top();
        NN.pop();
    }
}

And in kNN.hh:

class kNN {

private:
    struct CompareDist {
        bool operator()(int u1, int u2) {
            if (D[u1] < D[u2])
                return true;
            else
                return false;
        }
    };
...

However, this is giving me the error

kNN.hh: In member function ‘bool kNN::CompareDist::operator()(int, int)’:
kNN.hh:29: error: invalid use of nonstatic data member ‘kNN::D’

What can I do about this? It seems that C++ doesn't like it if I refer to specific objects in the comparator, but I have no idea how to solve this without referring to D.

Thanks!

Community
  • 1
  • 1
i love stackoverflow
  • 1,555
  • 3
  • 12
  • 24
  • This question isn't actually about priority queues and comparators, but about how inner classes can access data members of enclosing classes: http://stackoverflow.com/questions/486099/can-inner-classes-access-private-variables, http://stackoverflow.com/questions/1604853/nested-class-access-to-enclosing-class-private-data-members – jogojapan Nov 28 '12 at 03:44

2 Answers2

4

You may pass a reference to the D object into the constructor of the CompareDist object, and then use that D object in operator().

In this sample, I store a pointer to D. Depending upon the type of D, you may want to store a copy of D. (If D is a raw array, the syntax in my sample can be simplified.)

struct CompareDist {
    const DType* pD;
    CompareDist(const DType& D) : pd(&D) {}
    bool operator()(int u1, int u2) {
        return (*pD)[u1] < (*pD)[u2];
    }
};

priority_queue<int, vector<int>, CompareDist> NN(CompareDist(D));
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
-1

Ok, now I've read your question better and I can update the answer: the problem is that D is an object that is contained inside an instance of kNN, hence it is not static and can't be accessed from a static context.

You can solve the problem by using a static reference to D inside the class, something like

// .h
class kNN {
  static Type* current;
  ..

    struct CompareDist {
      bool operator()(int u1, int u2) {
        if ((*current)[u1] < (*current)[u2])
          return true;
        else
          return false;
      }
    };
}

// .cpp
Type *kNN::current = NULL;

void kNN::method()
{
  kNN::current = D; // beforing using the comparator
  ..
}

In addition signature should use elements by const reference, eg

bool operator()(const int &u1, const int &u2)
Jack
  • 131,802
  • 30
  • 241
  • 343
  • Sorry, I'm really confused about this. When am I referring to a specific instance of a collection? Also why do I need to pass a reference to an integer if it's just an integer and not an object? – i love stackoverflow Nov 28 '12 at 03:32
  • I updated the answer to reflect your specific situation, you need to pass by reference to avoid copying the value. – Jack Nov 28 '12 at 03:49
  • using static variables like this is not a good practice – Timo Nov 28 '12 at 04:54