Виртуальные обходные пути шаблона - PullRequest
1 голос
/ 10 июня 2011

У меня есть класс контейнера шаблонов, который я наследую и называю MyContainer. MyContainer определяет методы, такие как Get(), Set() и т. Д. Для доступа к отдельным элементам. Я хотел бы сделать класс битовых полей реализованным как MyContainer<char>, где каждый элемент char содержит CHAR_BIT количество битов. Однако, чтобы позволить пользователю работать с отдельными битами, а не с целыми байтами, я должен сделать виртуальные Get() и Set(), что недопустимо. Какие есть альтернативы?

Я думал об определении GetBit() и SetBit() в производном классе, но это нарушило бы принцип подстановки Лискова. (Подумайте о функции SortMyContainer().)

РЕДАКТИРОВАТЬ: Вот упрощенный пример:

template <typename Datatype>
struct MyContainer
{
    virtual Datatype Get();
};

template <typename Datatype> // Error: Templates may not be virtual.
virtual Datatype MyContainer<Datatype>::Get() // EDIT: The problem was on this line.  The "virtual" keyword should only appear with the function declaration.
{
    // ...
}

Ответы [ 2 ]

4 голосов
/ 10 июня 2011

Это не запрещено, только функции виртуального члена шаблона.

// valid
template<typename T> class MyContainer {
    virtual void set(const T &) = 0;
}

// not valid
class MyContainer {
    template <typename T> virtual void set (const T &) = 0;
}

Если я ошибся, рассмотрите возможность размещения образца кода.

изменить после добавления примера кода:

template <typename Datatype>
virtual // <-- nope, not here
Datatype MyContainer<Datatype>::Get()
{
    // ...
}

virtual является только частью объявления внутри тела класса. Это должно быть действительно:

template <typename Datatype>
Datatype MyContainer<Datatype>::Get()
{
    // ...
}

Однако обратите внимание, что определение должно быть видно в момент создания шаблона. Поэтому либо поместите его в файл заголовка (либо в дополнительный заголовок, который вы затем включите в свой настоящий заголовок), либо оставьте его в теле класса.

(пожалуйста, никто не упоминает export редактируемые шаблоны сейчас, мы с вами их много знаем, но они не совсем новичок, и устарели в следующем стандарте)

3 голосов
/ 10 июня 2011

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

template<typename T> class an_interface {
    virtual T Get() = 0;
};
class a_class : public an_interface<int> {
};

Это совершенно верно.Что не совсем верно, так это

class an_interface {
    template<typename T> virtual T Get() = 0;
}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...