Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I specialize a template which depends on a static data member of a class?

Consider the following code. I want to specialize std::hash<> used in a Map, according to the value of a static data member of the Array class. Note that Array depends on Map itself.

// Array.h
#include <unordered_map>

using namespace std;

class Array;
typedef pair<int, int> Point;

namespace std {
    template <> struct hash<Point> {
        size_t operator()(const Point & p) const {
            return p.second * Array::C + p.first; // error: incomplete type ‘Array’ used in nested name specifier
        }
    };
}

typedef unordered_map<Point, Array, hash<Point> > Map;

class Array {
public:
    static const int R = 5, C = 5;
    Map compute() {/*...*/}
};

Of course, in the above specialization Array is not complete yet, so the compiler complains. However, if I move the specialization below the class definition, I obtain another error:

error: specialization of ‘std::hash<std::pair<int, int> >’ after instantiation

like image 888
Martin Avatar asked Nov 20 '25 17:11

Martin


1 Answers

You are using the static member before the class is defined. Fix this by moving the implementation of hash after Array:

// Array.h
#include <unordered_map>

using namespace std;

class Array;
typedef pair<int, int> Point;

namespace std {
    template <> struct hash<Point>;
}

typedef unordered_map<Point, Array, hash<Point> > Map;
class Array {
public:
    static const int R = 5, C = 5;
    Map compute();
};

namespace std {
    template <> struct hash<Point> {
        size_t operator()(const Point & p) const {
            return p.second * Array::C + p.first;
        }
    };
}
like image 173
Kleist Avatar answered Nov 22 '25 06:11

Kleist



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!