vendredi 29 mars 2019

How to have variadic templates with a type and a size?

Just for fun I am trying to overload a struct, one for a std::array<T,SIZE>, one for a std::vector<T>, and a std::unordered_map<T,U>. So I did the following:

  template<typename... T>
  struct Cont; 

  template<typename T, std::size_t SIZE>
  struct Cont<T,SIZE>
  {
    Cont(std::string n) : name(n){}

    std::string name;
    std::array<T,SIZE> array;
  };

  template<typename T>
  struct Cont<T>
  {
    Cont(std::string n) : name(n){}

    std::string name;
    std::vector<T> vector;
  };

  template<typename T, typename U>
  struct Cont<T,U>
  {
    Cont(std::string n) : name(n){}

    std::string name;
    std::unordered_map<T,U> unordered_map;
  };

However, when I try to compile it, I get the error expected a type, got SIZE. Which I totally understand is because typename... T is expecting a type and not a std::size_t. So I tried:

template<std::size_t SIZE, typename... T>
struct Cont;

template<typename... T>
struct Cont;

Which also doesn't work since I am then redefining and not overloading like I originally thought I was doing. I also realize, that I can do:

template<std::size_t SIZE, typename... T>
struct Cont;

However I am trying to keep this as clean as possible in the sense when I declare them I want to be able to do:

int main()
{
  Cont<int,5> myArray("myArray");
  myArray.array = {1,2,3,4,5};

  Cont<int> myVector("myVector");
  myVector.vector = {1,2,3,4};

  Cont<int,int> myMap("myMap");
  myMap.unordered_map[0] = 2;
}

Is there a way to either overload the template? (I assume this is no) or construct a template in a way that says I'm either typename... T or typename T, std::size_t SIZE?

Aucun commentaire:

Enregistrer un commentaire