Как создать конкретный класс из шаблонного класса

Скажем, у меня есть шаблон класса:

template <typename T> class StringDeque:
public std::deque<T>
{
public:

...

private:
typedef std::deque<T> BaseClass;
};

Скажи, я хочу создать конкретный класс ArrayString где T=std::string,
Как правильно добиться этого:

определять

#define ArrayString StringDeque<string>

ЬурейеЕ

typedef StringDeque < string > ArrayString;

наследование

class ArrayString :
public StringDeque < string > {};

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

1

Решение

Правильные способы:

typedef std::deque<std::string> StringDeque;
using StringDeque = std::deque<string>;

Тем не менее, вот еще несколько замечаний по вашему вопросу:

Вы написали:

template <typename T> class StringDeque: public std::deque<T> // ...

std контейнерные классы не предназначены в качестве базовых классов. Это означает, что они не должны наследоваться от (а наследование от них — UB).

Когда вы хотите использовать std Функциональность контейнера в другом классе, ответ всегда должен быть инкапсуляции. Это означает, что правильный способ использовать функциональность std :: queue в ваших классах:

template<typename T> class StringDequeue {
std::deque<T> storage;
public:
// add interface here that uses storage
};

Вы также предложили это:

#define ArrayString StringDeque<string>

Пожалуйста, никогда не используйте define для объявления типа. Он работает, но имеет свои подводные камни и считается плохой практикой в ​​C ++.

2

Другие решения

Вы хотите дать имя определенному типу (который является экземпляром шаблона). C ++ способ давать имена (псевдонимы) типам с помощью typedef:

typedef StringDeque<string> ArrayString;

Или, начиная с C ++ 11, с объявлением псевдонима:

using ArrayString = StringDeque<string>;

Примечание: когда вы думаете об этом, это, как правило, помогает думать с точки зрения правильной терминологии шаблона. У вас нет «шаблона класса» ( учебный класс со специальными свойствами), у вас есть «шаблон класса» ( шаблон для создания классов). Шаблон не является типом; его экземпляры есть.

3

Создать псевдонимы типа с typedef или (начиная с C ++ 11) using:

typedef StringDeque<std::string> ArrayString;
using ArrayString = StringDeque<std::string>;

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

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

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector