How to declare data members that are objects of any type in a class

前端 未结 5 1766
夕颜
夕颜 2020-12-29 09:31

In this piece I\'m trying to declare in Class B a list that can hold objects of Class A of any type, such as A, A, A. I intend to add A

相关标签:
5条回答
  • 2020-12-29 09:41

    That's just not how C++ works. If you want to group different objects together, they need to have at least some relation. Being instantiations of the same class template doesn't imply that they are related, they're completely distinct types. If you want a list of A<T>*s, better make a list of base-class pointers and forward operations through virtual functions:

    class A_base{
    public:
      virtual void foo() = 0;
      virtual ~A_base() { }
    };
    
    template<class T>
    class A : public A_base{
    public:
      void foo(){
        // ...
      }
    };
    
    class B{
      std::list<A_base*> objects;
    };
    
    0 讨论(0)
  • 2020-12-29 09:41

    Member variables aren't allowed to be templates. Only member functions can be templates. You'll have to templatize the enclosing class B instead:

    template <class T>
    class B {
      std::list<A<T>*> objects;
    };
    
    0 讨论(0)
  • 2020-12-29 09:44

    Make B class template just like you've made A a class template:

    template<class T> 
    class B {
        std::list<A<T>*> objects;
    };
    
    0 讨论(0)
  • 2020-12-29 09:52

    Unfortunately you cannot have template variables. Only option to declare a member data is to make the class template:

    template<class T>
    class B {
        std::list<A<T>*> objects;
    };
    
    0 讨论(0)
  • 2020-12-29 09:58

    Depending on what you're doing, type erasure might be an option. On the Tension Between Object-Oriented and Generic Programming in C++ is my favorite write-up on the subject.

    In a nutshell, you convert the static dispatch enabled by the templates into dynamic dispatch through a custom inheritance tree you setup on the fly. Instead of storing A<T>, you create a new type that has the common interface you desire, and using some template/inhertiance voodoo this new type stores an A<T> without actually exposing the T. So A<int> and A<double> and A<A<std::list<A<int> > > > and some_type_that_looks_like_A_but_really_isnt all reduce down to a single type.

    But you have to have a common interface, independant of that parameter. If you can't, things get more difficult.

    Boost.Any is a good example, as is std::shared_ptr [which uses type erasure to remember how to delete the pointer passed to it even in the face of non-polymorphic inheritance].

    0 讨论(0)
提交回复
热议问题