Признаки типов C++ в методе класса: частичная специализация, если параметром является перечисление

Моя платформа — Windows с Visual Studio Express 2012.

У меня есть шаблонный метод следующим образом

struct A 
{
    template<class T> void blub(T value);
};

Я хочу иметь несколько специализаций, например:

template<> void A::blub(std::string value) { /* ... */ }
template<> void A::blub(int value) { /* ... */ }

Однако теперь я хотел бы включить перечисления, как-то так:

enum MyEnum { ENUM_1 };

A a;
a.blub(ENUM_1);

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

Выполнение чего-то вроде следующего приведет к сбою компиляции:

template<class T> void A::blub(const typename std::enable_if<std::is_enum<T>::value, T>::type& value) { /* ... */ }

Компилятор завершается с ошибкой C2244. Это имеет смысл, потому что компилятор вообще не может вывести тип для этого метода.

Что приводит меня к выводу: то, что я хочу, невозможно. Для вышеуказанного вызова мне нужно было бы сделать следующее:

A a;
a.blub((int)ENUM_1);

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


person bobbel    schedule 18.09.2013    source источник


Ответы (1)


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

struct A
{
    template<typename T>
    typename std::enable_if<std::is_enum<T>::value>::type
    blub(T value);

    // and don't specialize for concrete types,
    // just overload:

    void blub(std::string value);
    void blub(int value);
};

Живой пример.

person jrok    schedule 18.09.2013