Storing templated objects in a vector (Storing Class<int>, Class<double> in a single vector)

断了今生、忘了曾经 提交于 2019-12-13 14:33:11

问题


There is a templated class, let it be

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

The problem I am facing here is, users can create several types of this class, but I need to track them, best case is I have a reference of these objects in another vector, but that would not work since all types are different. Can you recommend a good design pattern which can encapsulate this.

I can store pointers and then typecast it, but its not elegant.

I can change the architecture as well, if the solution provided is good enough. The basic question I am trying to solve is, I have a class of vector of custom types, how do I store them.


回答1:


As previous comments stated - you first need to make sure this is what you need.

With that been said, I had a similar requirement in a project of mine, which I eventually solved with inheritance and PIMPL, as follows:

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();}
};

This allows you to create a container of objects of type 'A', and access them via the public interface defined therein (the method 'f'). The underlying type 'T' of each 'A' object is specified on construction. All other implementation details specific to the type 'T' are hidden.

The solution suffers the inherent overhead of virtual functions. I'm not sure how it compares to the std::any approach performance-wise.




回答2:


std::any is the modern c++17 solution. Specifically, you should use

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.
}

These pointers can point into the A<int>::data and A<double>::data vectors.

For a complete reference, see here https://en.cppreference.com/w/cpp/utility/any.



来源:https://stackoverflow.com/questions/54454874/storing-templated-objects-in-a-vector-storing-classint-classdouble-in-a-si

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!