2016-05-28 5 views
2

Я следующий код (очень упрощенным для ясности):функция член Specialize шаблонного производного класса

class Base 
{ 
    virtual int DoStuff(int arg) = 0; 
}; 

template <typename T> 
class Derived : public Base 
{ 
    int DoStuff(int arg) override 
    { 
     // do some stuff 
     return 0; 
    } 
}; 

Это прекрасно работает. Теперь я хочу реализовать специальную (векторизованную) реализацию DoStuff. И мне нужно реализация быть конкретными на основе типа T, что производный есть, что-то вроде этого:

class Base 
{ 
    virtual int DoStuff(int arg) = 0; 
    virtual int DoStuffVectorized(int arg) = 0; 
}; 

template <typename T> 
class Derived : public Base 
{ 
    int DoStuff(int arg) override 
    { 
     // do some stuff 
     return 0; 
    } 

    int DoStuffVectorized<char>(int arg) override 
    { 
     // do some stuff for T == char 
     return 0; 
    } 

    int DoStuffVectorized<int>(int arg) override 
    { 
     // do some stuff for T == int 
     return 0; 
    } 
}; 

Однако я не в состоянии сделать эту работу.

EDIT: Я получаю следующее сообщение об ошибке: ошибка C2143: синтаксическая ошибка: отсутствует ';' до «<» на линии int DoStuffVectorized<char>(int arg) override.

Когда я изменить его на: template<char> int DoStuffVectorized(int arg) override я получаю: C2898 ошибки: ... ': шаблоны функций член не может быть виртуальной

Любые советы о том, как добиться чего-то вроде этого? Причина, в которой я нуждаюсь, в том, что у меня есть std :: vector, который хранит данные разных типов (используя Derived <>). Таким образом, я могу использовать один и тот же простой код независимо от того, какой тип хранится, и я хочу, чтобы это было правдой даже при использовании специальной векторизованной реализации DoStuff, которая печально специфична для конкретного типа.

+1

Что означает «Я не могу заставить его работать»? –

+1

«Однако я не могу сделать эту работу» Почему? Любые сообщения об ошибках? Что не работает? – user463035818

+0

Добавлены сообщения об ошибках. Мне кажется, что я теряюсь в некоторых синтаксических ошибках определения наследования/шаблона? – PeterK

ответ

3

Вы должны специализироваться функции члена шаблона вне класса:

#include <iostream> 

class Base 
{ 
    public: 
    virtual int DoStuffVectorized(int arg) = 0; 
}; 

template <typename T> 
class Derived : public Base 
{ 
    public: 
    int DoStuffVectorized(int arg) override; 
}; 

template <> 
int Derived<char>::DoStuffVectorized(int arg) 
{ 
    std::cout << "T == char\n"; 
    return 0; 
} 

template <> 
int Derived<int>::DoStuffVectorized(int arg) 
{ 
    std::cout << "T == int\n"; 
    return 0; 
} 

int main(){ 
    Derived<char> c; 
    Derived<int> i; 
    Base* b[] = { &c, &i }; 
    for(auto* x : b) 
     x->DoStuffVectorized(0); 
    // undefined reference to `Derived<double>::DoStuffVectorized(int)' 
    // Derived<double> d; 
} 

Если вы хотите, чтобы захватить непреднамеренные инстанциацию во время компиляции:

#include <type_traits> 

// A std::false_type (useful in a static_assert) 
template <typename T> 
struct static_false : std::false_type 
{}; 

template <typename T> 
int Derived<T>::DoStuffVectorized(int arg) 
{ 
    static_assert(static_false<T>::value, "Neither 'char' or 'int'"); 
    return 0; 
} 
+0

Вы не думаете, что у нас должна быть одна родовая общая перегрузка для DoStuffVectorized иначе что-то вроде Derived f не будет работать – Kapil

+0

Спасибо, это именно то, что я хочу! – PeterK

+0

Но зачем усложнять материал std :: false_type, почему бы прямо не использовать static_assert (false, «Ни« char », ни« int »); – Kapil

2

DoStuffVectorized<char> неправильный синтаксис, DoStuffVectorized не является самим шаблоном.

См template specialization:

template <typename T> 
class Derived : public Base 
{ 
    int DoStuff(int arg) override 
    { 
     // do some stuff 
     return 0; 
    } 
    int DoStuffVectorized(int arg) override 
    { 
     // do some stuff (primary template) 
     return 0; 
    } 
}; 

template <> 
int Derived<int>::DoStuffVectorized(int) { 
    // do some stuff for T == char 
    return 0; 
} 

template <> 
int Derived<char>::DoStuffVectorized(int) { 
    // do some stuff for T == char 
    return 0; 
} 
Смежные вопросы