用于在C++中存储特定模板对象的通用容器

Generic container to store objects of a particular template in C++

本文关键字:对象 C++ 存储 用于      更新时间:2023-10-16

我正在尝试创建一个通用容器,它可以存储 Wrappertemplate <typename T> class Wrapper{ public: Wrapper(const T& a):o(a){}; Wrapper(){}; //public methods void foo(){ //do stuff }; private: T o; }; class X{}; class Y{}; int main(){ X x; Y y; A_GENERIC_CONTAINER generic_container; // A_GENERIC_CONTAINER should be able to store // any number of heterogeneous objects of type Wrapper<T> // where T can be any user defined type. generic_container.push_back(x); generic_container.push_back(y); auto it = generic_container.begin(); auto end = generic_container.end(); while(it != end){ it->foo(); ++it; } }

最通用的方法是为 Wrapper 创建一个基类,比如 BaseWrapper,并在 BaseWrapper 上定义纯虚函数,然后在每个 Wrapper 类上实现这些函数。 通过专业化,每个包装器,包装器,都可以有自己的实现。 完成此操作后,您可以使用指向基本类型的智能指针容器,并在闲暇时使用它。

有一些可能的捷径。 例如,在您的示例中的简单情况下,我建议使用std::function. 帮助程序函数有助于执行此操作。 请注意,这实际上仅在只有 1 个方法要调用时才有效。 我还建议您的包装器直接定义operator(),这样您就不必使用绑定。

template<T>
std::function<void()> wrap(const T& x)
{
return std::bind(&Wrapper<T>::foo, Wrapper<T>(x));
}
int main(){
X x;
Y y;
std::vector<std::function<void()> > generic_container;
// A_GENERIC_CONTAINER should be able to store
// any number of heterogeneous objects of type Wrapper<T>
// where T can be any user defined type.
generic_container.push_back(wrap(x));
generic_container.push_back(wrap(y));
auto it =  generic_container.begin();
auto end =  generic_container.end();
while(it != end){
(*it)();
++it;
}
}

编辑:

我讨论的是一个非模板化的基础,你从中派生出所有的模板化包装器。 这允许您调用预定义的方法(必须由包装器实现),而无需知道所涉及的特定包装器类型。

class Base
{
public:
virtual ~Base() {};
virtual void foo() = 0;
};
template <typename T>
class Wrapper : public Base{
public:
Wrapper(const T& a):o(a){};
Wrapper(){};
//public methods
virtual void foo(){
//do stuff
};
private:
T o;
};
int main(){
X x;
Y y;
std::vector<std::shared_ptr<Base> > generic_container;
// A_GENERIC_CONTAINER should be able to store
// any number of heterogeneous objects of type Wrapper<T>
// where T can be any user defined type.
generic_container.push_back(std::make_shared<Wrapper<X>>(x));
generic_container.push_back(std::make_shared<Wrapper<Y>>(y));
auto it =  generic_container.begin();
auto end =  generic_container.end();
while(it != end){
it->foo();
++it;
}
}