Подтвердить что ты не робот

Получение "незаконного использования явных аргументов шаблона" при выполнении частичной специализации указателя для метода класса

Привет, у меня проблемы с частичной специализацией. То, что я хочу сделать, это иметь класс, который имеет функцию члена шаблона, которая будет интерпретировать заданное значение одному, указанному пользователем. Например, имя класса Value, и вот фрагмент того, что я хочу сделать:

int *ptr1 = new int;
*ptr1 = 10;
Value val1 = ptr1;
int *ptr2 = val1.getValue<int*>();

Value val2 = 1;
int testVal = val2.getValue<int>();

Вот как я реализовал такой класс:

struct Value {

    Value(void *p) : val1(p){}
    Value(int i) : val2(i){}

    template<typename T>
    T getValue();

    void *val1;
    int val2;
};

template<typename T>
T*  Value::getValue<T*>() {
    return reinterpret_cast<T*>(val1);
}

template<>
int Value::getValue<int>() {
    return val2;
}

При компиляции я получаю следующую ошибку:

ошибка C2768: "Значение:: getValue": незаконное использование явного шаблона Аргументы

В основном, он жалуется на часть шаблона указателя кода:

template<typename T>
T* Value::getValue<T*>() {
    return reinterpret_cast<T*>(val1);
}

Я знаю, что эта проблема может быть реализована с помощью простого объединения, но этот код является урезанной версией более крупного кода.

Кто-нибудь знает, в чем проблема? То, что я хотел бы сделать, это отдельный код для использования указателей и других, если не использовать указатели. Я действительно застрял, и я всегда расследую, а не спрашиваю, но я не нашел никакой хорошей информации об этом.

4b9b3361

Ответ 1

Шаблоны функций не могут быть частично специализированными, но большую часть времени вы можете использовать трюк делегата к классу. В вашем примере это будет так:

struct Value {
  template<typename T>
  T getValue() {
    return Impl_getValue<T>::call(*this);
  }
};

template <typename T>
struct Impl_getValue
{
  static T call(Value &v) {
    //primary template implementation
  }
};

template <typename T>
struct Impl_getValue<T*>
{
  static T* call(Value &v) {
    return reinterpret_cast<T*>(v.val1);
  }
};