Как поместить разные типы шаблонов в один вектор - PullRequest
8 голосов
/ 30 марта 2009

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

template <typename T> class Argument {
public:
    int size;
    int type;
    T data;
};

и с некоторыми перегруженными

addMessage (int value) {
    Argument<int> *a = new Argument<int>;
    vec.push_back(a);
}

(то же самое для строки и т. Д.) Я пытаюсь объединить все в один вектор. Я пытался

std::vector<Argument* > vec;
std::vector<Argument<typename T>* > vec;
std::vector<Argument<>* > vec;

но, похоже, ничего из этого не работает. Есть ли способ сделать это? Заранее спасибо.

Ответы [ 3 ]

13 голосов
/ 30 марта 2009

Вариант 1: убедитесь, что все различные типы аргументов происходят из базового класса и используют указатели на этот класс. Обратите внимание, что эта опция рискованна с точки зрения управления памятью. Возможно, вы захотите сделать это безопаснее, используя boost :: shared_ptr вместо указателей. В противном случае вы должны очистить вручную, когда элемент удаляется из вектора.

Вариант 2 (мой личный фаворит): используйте Boost.Variant , чтобы сделать typedef для всех возможных типов аргументов и используйте этот typedef в качестве типа аргумента в std :: vector

typedef boost::variant<ArgumentType1, ArgumentType2, ArgumentType3> ArgumentType;
std::vector<ArgumentType> vec;
6 голосов
/ 30 марта 2009

Самый простой способ сделать это - иметь базовый класс Argument, который не является шаблонным, и затем получить из него определенные типы данных. (Вы можете даже сделать шаблонную версию производной от базового класса напрямую и просто использовать эти два класса.) Затем вы сохраняете их как указатели в векторе.

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

4 голосов
/ 30 марта 2009

Вы можете использовать буст :: вариант (http://www.boost.org/doc/libs/1_38_0/doc/html/variant.html)
или повышение :: любой (http://www.boost.org/doc/libs/1_38_0/doc/html/any.html) тип

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

Но я не уверен, что использование подобных типов - это хороший дизайн.

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