Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ class with template member variable

I am trying to solve a programming problem that consists of an object (call it Diagram), that contains several parameters. Each parameter (the Parameter class) can be one of several types: int, double, complex, string - to name a few.

So my first instinct was to define my Diagram class as having a vector of template parameters, which would look like this.

class Diagram { private:     std::vector<Parameter<T> > v; }; 

This doesn't compile, and I understand why. So, based on the recommendations on this page How to declare data members that are objects of any type in a class, I modified my code to look like:

class ParameterBase { public:     virtual void setValue() = 0;     virtual ~ParameterBase() { } };   template <typename T> class Parameter : public ParameterBase { public:     void setValue() // I want this to be                      // void setValue(const T & val)     {         // I want this to be          // value = val;     }  private:     T value; };  class Diagram { public:     std::vector<ParameterBase *> v;     int type; }; 

I'm having trouble figuring out how to call the setValue function with an appropriate templated parameter. It is not possible to have a templated parameter in the ParameterBase abstract base class. Any help is greatly appreciated.

P.S. I don't have the flexibility to use boost::any.

like image 609
endbegin Avatar asked Dec 20 '12 20:12

endbegin


People also ask

How do I declare a template variable?

A variable template may be introduced by a template declaration at namespace scope, where variable-declaration declares a variable. When used at class scope, variable template declares a static data member template.

Can a member function be a template?

Member functions can be function templates in several contexts. All functions of class templates are generic but are not referred to as member templates or member function templates. If these member functions take their own template arguments, they are considered to be member function templates.

Can a class member function template be virtual in C++?

No, template member functions cannot be virtual.

Can a non template class have a template member function?

A non-template class can have template member functions, if required. Notice the syntax. Unlike a member function for a template class, a template member function is just like a free template function but scoped to its containing class.


1 Answers

You got very close. I added a few bits because they're handy

class ParameterBase { public:     virtual ~ParameterBase() {}     template<class T> const T& get() const; //to be implimented after Parameter     template<class T, class U> void setValue(const U& rhs); //to be implimented after Parameter };  template <typename T> class Parameter : public ParameterBase { public:     Parameter(const T& rhs) :value(rhs) {}     const T& get() const {return value;}     void setValue(const T& rhs) {value=rhs;}     private:     T value; };  //Here's the trick: dynamic_cast rather than virtual template<class T> const T& ParameterBase::get() const { return dynamic_cast<const Parameter<T>&>(*this).get(); } template<class T, class U> void ParameterBase::setValue(const U& rhs) { return dynamic_cast<Parameter<T>&>(*this).setValue(rhs); }  class Diagram { public:     std::vector<ParameterBase*> v;     int type; }; 

Diagram can then do stuff like these:

Parameter<std::string> p1("Hello"); v.push_back(&p1); std::cout << v[0]->get<std::string>(); //read the string v[0]->set<std::string>("BANANA"); //set the string to something else v[0]->get<int>(); //throws a std::bad_cast exception 

It looks like your intent is to store resource-owning pointers in the vector. If so, be careful to make Diagram have the correct destructor, and make it non-copy-constructable, and non-copy-assignable.

like image 187
Mooing Duck Avatar answered Sep 22 '22 13:09

Mooing Duck