0

I have a situation where I need a class FaceProp that maintains/holds other classes for actual face types. These could be any types of faces like boundary faces, solid faces, internal faces etc etc. I wanted to implement FaceProp using the variadic parameter pack feature in C++, but I am not sure how this can be achieved.

I am attempting the following main class

 template<typename... FaceTypes>
 class FaceProp 

 {
     FaceProp(){
         /// here construct all those template argument classes. 
      }

  private:

   // declare here the classes to the FaceTypes.
   // e.g. If this class was declared with two face types I would have :
   //   std::unique_ptr<FaceType1> type1;
   //   std::unique_ptr<FaceType2> type2;

 }

I am not sure how declaring those would work since by the time of implementing I don't know how many/ and which face types I need to deal with. This is known by compiling time. In other words, when I want to declare the class FaceProp I would know how many face types to use

e.g.

 std::unique_ptr<FaceProp<facetype1, facetype2>> allfaces;

How is this best achieved?

ATK
  • 1,296
  • 10
  • 26
  • 1
    I think this case may be better solved with interface. – apple apple Mar 04 '21 at 19:46
  • But how are related the `FaceTypes` to `FaceProp`? `FaceProp` inherit from all `FaceTypes`? `FaceProp` must contain a `std::tuple`? Or a `std::variant`? – max66 Mar 04 '21 at 19:52
  • `std::tuple` is the way to go. Otherwise you essentially need to reimplement the tuple, which is not trivial. – HolyBlackCat Mar 04 '21 at 19:53
  • @HolyBlackCat could you elaborate please? Also, do you have any good ref on variadic template argument, feel like I am not understanding the concept as I should – ATK Mar 04 '21 at 22:28

1 Answers1

1

An example of how to do this using std::tuple as suggested in the comments. I showed it with and without std::unique_ptr.

template <typename... FaceTypes>
class FaceProp
{
   FaceProp() {
      m_tuple = {FaceTypes()...};
      m_uniqueTuples = {std::make_unique<FaceTypes>()...};
   }

private:
   std::tuple<FaceTypes...> m_tuple;
   std::tuple<std::unique_ptr<FaceTypes>...> m_uniqueTuples;
};

The ... in the code expands the associated expression to include each type in the parameter pack. So, FaceProp<int, double> expands to:

class FaceProp
{
   FaceProp() {
      m_tuple = {int(), double()};
      m_uniqueTuples = {std::make_unique<int>(), std::make_unique<double>()};
   }

private:
   std::tuple<int, double> m_tuple;
   std::tuple<std::unique_ptr<int>, std::unique_ptr<double>> m_uniqueTuples;
};
Dean Johnson
  • 1,682
  • 7
  • 12