Janette Vlasicia
Janette Vlasicia

Reputation: 19

Simplify template arguments

I need to create a template class depending on a simple struct like this. It has a method AddNew to insert new element for its tuple member.

struct Type
{
  int i;
  char c;
};

template<typename ...T>
class A
{
   std::tuple<T...> ts;
   public:
     A(T&&...t):ts(std::move(t)...){}
     void AddNew(T t)
     {
        ts=std::tuple_cat(ts,t);
     }
};

int main()
{
   A<Type,Type,Type,Type> a({1,'a'},{2,'t'},{3,'c'},{4,'g'});
   Type t{5,'x'};
   a.AddNew(t);
}

Problem I don't want to write down Type... 4 times like in main. I like something like A<Type,4> when I initialize A with 4 Types or A<Type, 100> for 100 Types.

Upvotes: 0

Views: 57

Answers (2)

Jarod42
Jarod42

Reputation: 218323

You probably just want vector:

struct Type
{
  int i;
  char c;
};

template<typename T>
class A
{
   std::vector<T> data;
   public:
     template <typename ... Ts>
     A(Ts&&...ts) : data(std::forward<Ts>(ts)...){}

     void AddNew(const T& t)
     {
        data.push_back(t);
     }
};

int main()
{
   A<Type> a(Type{1,'a'}, Type{2,'t'}, Type{3,'c'}, Type{4,'g'});
   Type t{5,'x'};
   a.AddNew(t);
}

Upvotes: 3

Massimiliano Janes
Massimiliano Janes

Reputation: 5624

you may partially specialize A for some helper 'tag' type:

template<typename T, std::size_t N>
struct repeat{};

template<typename... T>
struct repeat_unpack{ using type = A<T...>; };

template<typename T, int N, typename... V >
struct repeat_unpack<repeat<T,N>,V...>: std::conditional_t<(N>1),
    repeat_unpack<repeat<T,N-1>,T,V...>,
    repeat_unpack<T,V...>
 >{};

template<typename T, int N>
class A<repeat<T,N>>: repeat_unpack<repeat<T,N>>::type {};

// to be used as
A<repeat<Type,3>>

the above uses inheritance to avoid code duplication, so you'll probably need to lift some members (eg. constructors) to the partial specialization as well. Otherwise, just use an alias

template<class T, std::size_t N>
using A_nth = typename repeat_unpack<repeat<T,N>>::type;

A_nth<Type,3>

Just one more thing, given that you're using tuple internally, it should be easy to simply specialize for std::array and use it instead, being tuple compatible ...

PS. obviously, your AddNew() code makes no sense as is, I'd assume it's just a code snippet typo ...

Upvotes: 0

Related Questions