C++: store/remember type of template class
假设我们有一个类似以下的类:
1 2 3 4 5 6 7 8 | class AbstractContainer{ ... }; template <typename T> class Container : public AbstractContainer { T someFunction(); }; |
现在,有另一个类具有一个成员变量,该成员变量将存储这些容器之一。但是,模板类型不应固定。因此,不是将成员变量声明为
1 2 3 4 5 6 7 | class Interface{ public: Interface(); void doSth(); private: AbstractContainer* container; }; |
假设容器是在
1 2 3 4 5 6 7 8 | Interface::Interface(){ if (/* some condition */) this->container = new Container<int>(25); } else { this->container = new Container<float>(25); } //here I'd need to remember of which type container is: int or float } |
因此,在这里我需要以某种方式存储我的容器是哪种类型(
1 2 3 4 5 6 7 8 | void Interface::doSth(){ //here I have to recall what the type was if(/* type was int */) { dynamic_cast<Container<int>&>(*(this->container)).someFunction(); } else { dynamic_cast<Container<float>&>(*(this->container)).someFunction(); } } |
我曾考虑过使用包含所有受支持类型的值的
我基本上想做的是存储
编辑:我必须弄清楚函数
你可以做
1 2 3 4 5 6 7 | void Interface::doSth(){ if (auto* c_int = dynamic_cast<Container<int>*>(this->container)) { c_int->someFunction(); } else if (auto* c_float = dynamic_cast<Container<float>*>(this->container)) { c_float->someFunction(); } } |
但是,为什么不将
可能是您的答案是奇怪的重复模板模式。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | template<class T, template<class> class U> class AbstractContainer { void interface() { static_cast<U< T > *>(this)->implementation(); } }; template<class T> class Container : public AbstractContainer<T, Container> { void implementation() { } }; |
尽管Jarod42的答案更好,但是一种实现方法是使用
1 2 3 4 5 6 7 8 9 10 11 | void doSth() { if (typeid(*container).hash_code() == typeid(Container<int>).hash_code()) { cout <<"int" << endl; } else if (typeid(*container).hash_code() == typeid(Container<float>).hash_code()) { cout <<"float" << endl; } } |
但是在基类中至少需要一个虚函数。 例如,您可以创建虚拟析构函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | class AbstactObject { public: virtual ~AbstractObject() = 0; virtual AbstractObject &doSomething() = 0; } template<class T> class Object : AbstactObject { public: virtual ~Object(); virtual Object< T > &doSomething(); T &get(); private: T t; } class AbstractContainer { public: virtual ~AbstractObject() = 0; virtual AbstractObject &doSomething(); private: AbstractObject *obj; }; template<class T> class Container : AbstactContainer { public: virtual ~Container(); virtual Object< T > &doSomething() { return obj->doSomething(); }; } class Interface { public: Interface(); void doSth(); private: AbstractContainer* container; }; Interface::Interface() { if (/* some condition */) container = new Container<int>(25); } else { container = new Container<float>(25); } } void Interface::doSth() { auto obj = container->doSomething(); auto val = obj.get(); } |
当你想获得T值时
1 2 | auto obj = container->doSomething(); auto val = obj.get(); |
请检查:协变返回类型
https://zh.wikipedia.org/wiki/Covariant_return_type
另一种选择:
1 2 3 4 | template <class T> T doSth(Container< T > &container){ return container.someFunction(); //assume someFunction returns a T } |
您不需要基类,继承,演员表。