Search code examples
c++objectfunctor

Expression preceding parentheses must have pointer-to- function type when using functors


So, as the title states, I'm struggling to use a functor for my game server map class. I've defined the following template class to represent the sectored 3D map:

template <typename T>
class matrix3d {
public:
    matrix3d(uint16_t XMin, uint16_t XMax, uint16_t YMin, uint16_t YMax, uint8_t ZMin, uint8_t ZMax);

    T* operator() (uint16_t x, uint16_t y, uint8_t z);

private:
    uint16_t xmin, xmax;
    uint16_t ymin, ymax;
    uint8_t zmin, zmax;

    int16_t dx, dy;
    int8_t dz;

    T* Entry; // This is an array that I new() in the class constructor.
};

At the start of the server I new a global instance that will hold the map matrix3d<TSector *> *g_Map(TSector being a struct holding a 2-dimensional 32x32 array of tiles and its flags and stuff).

I decided to overload the () operator to retrieve a TSector* given the corresponding coordinates from the map files:

template<typename T>
T* matrix3d<T>::operator() (uint16_t x, uint16_t y, uint8_t z) {
    uint16_t xx = x - xmin;
    uint16_t yy = y - ymin;
    uint8_t zz = z - zmin;

    if (xx >= 0 && xx < dx
     && yy >= 0 && yy < dy
     && zz >= 0 && zz < dz)
        return &Entry[xx + dy * dx * zz + dx * yy];

    error("matrix3d::operate: Unexpected Index %d/%d/%d.\n", x, y, z);
    return Entry;

}

So, my problem relies at the moment of compiling this function: LoadSector(filename, x, y, z), which gets called for each sector file (I have about 10.000 of these files) and retrieves the respective sector from g_Map to store the parsed tile contents:

void LoadSector(const char* FileName, uint16_t x, uint16_t y, uint8_t z) {
    TSector* sector = g_Map(x, y, z); // My actual problems is here.

    // BEGIN PARSING.
}

VS Code says: "expression preceding parentheses of apparent call must have (pointer-to-) function type". g++ says: g_Map cannot be used as a function.


Solution

  • g_Map is a pointer to a matrix3d. In order to invoke your operator() on that matrix3d object, you need to first dereference the pointer:

    TSector* sector = (*g_Map)(x, y, z);
    

    Which is equivalent to:

    TSector* sector = (*g_Map).operator()(x, y, z);
    

    Alternatively :

    TSector* sector = g_Map->operator()(x, y, z);