Хранение шаблонных объектов в векторе (Хранение Class <int>, Class <double>в одном векторе) - PullRequest
0 голосов
/ 31 января 2019

Существует шаблонный класс, пусть он будет

template<typename T> class A { std::vector<T> data; };

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

Я могу хранить указатели, а затем печатать их, но это не элегантно

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

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Как говорилось в предыдущих комментариях - сначала нужно убедиться, что это именно то, что вам нужно.

С учетом сказанного у меня возникло аналогичное требование в моем проекте, который я в итоге решил с помощью наследования и PIMPL, следующим образом:

class A{
private:
    struct Abstract {
        virtual void f() = 0;
    };

    template <typename T>
    struct Implementation : public Abstract {
        std::vector<T> data;
        virtual void f() {...}
    };

    std::unique_ptr<Abstract> impl;

public:
    template <typename T>
    A(): impl(std::make_unique<Implementation<T> >()){}

    void f() {impl->f();}
};

Это позволяет вам создать контейнер объектов типа 'A' и обращаться к ним через определенный в нем открытый интерфейс (метод 'f').Базовый тип 'T' каждого объекта 'A' указан в конструкции.Все другие подробности реализации, специфичные для типа 'T', скрыты.

Решение страдает от накладных расходов виртуальных функций.Я не уверен, как это соотносится с std :: any подход с точки зрения производительности.

0 голосов
/ 31 января 2019

std::any - это современное решение c ++ 17.В частности, вы должны использовать

A<int> a;
a.data.push_back(0);

// fill refernces...
std::vector<std::any> refernces; 
refernces.push_back(&a.data[0]);

// check which type is active.
if(int** iPtr = std::any_cast<int*>(&references[0]); iPtr != nullptr)
{
     // its an int*
     int& i = **iPtr;
     // do something with i.
}

. Эти указатели могут указывать на векторы A<int>::data и A<double>::data.

Полный справочник см. Здесь https://en.cppreference.com/w/cpp/utility/any.

...