Stewart
Stewart

Reputation: 4992

Adding more types to template specialization

I have a simple templated class which I instantiate for each type that uses it like so:

template<class T> struct meta {
  static const std::string& get_name() {return T::class_name;}
};

template<> struct meta<double> {
  static constexpr const char* class_name = "double";
  static const char* get_name() { return class_name; }
};

template<> struct meta<std::vector<double> {
  static constexpr const char* class_name = "std::vector<double>";
  static const char* get_name() { return class_name; }
};

template<> struct meta<std::array<double,2>> {
  static constexpr const char* class_name = "double[]";
  static const char* get_name() { return class_name; }
};

Then I can use these like so:

int main() {
  std::cout << meta<double>::get_name() << '\n';
  std::cout << meta<std::vector<double> >::get_name() << '\n';
  std::cout << meta<std::array<double,2> >::get_name() << '\n';
}

I use macros to generate variants of the template-specialization for each base-type, but I'm stuck on std::array because it contains a base-type and an integer. I'd like to find out how to add a new templated parameter to an already-templated specialization so that I don't need to specialize for each possible value of integer.

I've tried:

template<int I> struct meta<std::array<double,I>> {
    static constexpr const char* class_name = "double[]";
    static const char* get_name() { return class_name; }
};

error: ‘class_name’ is not a member of ‘std::array’

Upvotes: 1

Views: 68

Answers (1)

user202729
user202729

Reputation: 3945

From the std::array C++ documentation:

template< 
    class T, 
    std::size_t N 
> struct array;

So, you need

template<std::size_t I> struct meta<std::array<double, I>> {
    static constexpr const char* class_name = "double[]";
    static const char* get_name() { return class_name; }
};

Because int and std::size_t are two different types (having different signed-ness), the partial template specialization won't match. Changing int to size_t works.


In summary: Read the documentation.

Upvotes: 2

Related Questions