C++ One std::vector containing template class of multiple types -


i need store multiple types of template class in single vector.

eg, for:

template <typename t> class templateclass{      bool somefunction(); }; 

i need 1 vector store of:

templateclass<int> t1; templateclass<char> t2; templateclass<std::string> t3; etc 

as far know not possible, if how?

if isn't possible explain how make following work?

as work around tried use base, non template class , inherit template class it.

 class templateinterface{      virtual bool somefunction() = 0;  };   template <typename t>  class templateclass : public templateinterface{      bool somefunction();  }; 

i created vector store base "templateinterface" class:

std::vector<templateinterface> v; templateclass<int> t; v.push_back(t); 

this produced following error:

error: cannot allocate object of abstract type 'templateinterface' note: because following virtual functions pure within 'templateinterface' note: virtual bool templateinterface::somefunction() 

to fix error made function in templateinterface not pure virtual providing function body, compiled when calling function overide not used, instead body in virtual function.

eg:

 class templateinterface{      virtual bool somefunction() {return true;}  };   template <typename t>  class templateclass : public templateinterface{      bool somefunction() {return false;}  };   std::vector<templateinterface> v;  templateclass<int> i;  v.push_back(i);  v[0].somefunction(); //this returns true, , not use code in 'templateclass' function body 

is there way fix overridden function used, or there workaround store multiple template types in single vector?

why code doesn't work:

calling virtual function on value doesn't use polymorphism. calls function defined type of exact symbol seen compiler, not runtime type. when insert sub types vector of base type, values converted base type ("type slicing"), not want. calling functions on them call function defined base type, since not is of type.

how fix this?

the same problem can reproduced code snippet:

templateinterface x = templateclass<int>(); // type slicing takes place! x.somefunction();  // -> templateinterface::somefunction() called! 

polymorphism works on pointer or reference type. use runtime type of object behind pointer / reference decide implementation call (by using it's vtable).

converting pointers totally "safe" regard type slicing. actual values won't converted @ , polymorphism work expected.

example, analogous code snippet above:

templateinterface *x = new templateclass<int>();  // no type slicing takes place x->somefunction();  // -> templateclass<int>::somefunction() called!  delete x;  // don't forget destroy objects. 

what vectors?

so have adopt these changes in code. can store pointers actual types in vector, instead of storing values directly.

when working pointers have care deleting allocated objects. can use smart pointers care deletion automatically. unique_ptr 1 such smart pointer type. deletes pointee whenever goes out of scope ("unique ownership" - scope being owner). assuming lifetime of objects bound scope should use:

std::vector<std::unique_ptr<templateinterface>> v;  templateclass<int> *i = new templateclass<int>();    // create new object v.push_back(std::unique_ptr<templateinterface>(i));  // put in vector  v.emplace_back(new templateclass<int>());   // "direct" alternative 

then, call virtual function on 1 of these elements following syntax:

v[0]->somefunction(); 

make sure make functions virtual should possible overridden subclasses. otherwise overridden version not called. since introduced "interface", i'm sure working abstract functions.

alternative approaches:

alternative ways want use variant type in vector. there implementations of variant types, boost.variant being popular one. approach nice if don't have type hierarchy (for example when store primitive types). use vector type std::vector<boost::variant<int, char, bool>>


Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -