Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template argument for non-type parameter must be an expression

Tags:

c++

templates

Why is the following code wrong?

template <typename T, int N>
struct Vector {
    T data[N];
};

struct Dynamic {
};

template <typename T>
struct Vector<T, Dynamic> {
    T* data;
};

I tried to instantiate the code with Vector<int, Dynamic> obj; and it didn't work

error: template argument for non-type template parameter must be an expression

Why? I'm passing a type and I thought that was a valid template specialization.

How can I use two templates and having one that requests N and one that doesn't if marked with Dynamic ?

like image 324
Dean Avatar asked Feb 06 '23 18:02

Dean


2 Answers

template <typename T, int N>
struct Vector {
    T data[N];
};

Here in your primary template class, T must be a type, (int, short, class-type, etc)... N is a non-type, and must be an expression that evaluates to an int type (a number).

struct Dynamic {
};

template <typename T>
struct Vector<T, Dynamic> {
    T* data;
};

Dynamic is a type. Not an int as specified in your primary template


Based on your primary template class, you can only specialize the second template parameter of Vector with an int. Eg.

template <typename T>
struct Vector<T, 1> {
    T* data;
};

template <typename T>
struct Vector<T, 35> {
    T* data;
};

template <typename T>
struct Vector<T, constExpressionThatReturnsAnInt> {
    T* data;
};

...etc
like image 142
WhiZTiM Avatar answered Feb 09 '23 07:02

WhiZTiM


You cannot use Dynamic to specialization Vector because Dynamic is a class and your primary template expect an int. What you want is probably something like:

#include <limits>

constexpr size_t Dynamic = std::numeric_limits<size_t>::max();

template <typename T, size_t N>
struct Vector {
    T data[N];
};

template <typename T>
struct Vector<T, Dynamic> {
    T* data;
};

Vector<int, 10> static_array;
Vector<int, Dynamic> dynamic_array;

Here Dynamic is a constexpr of the correct type (size_t), so you can specialize your template. You will simply not be able to create static array of size std::numeric_limits<size_t>::max() (which should not be an issue).

like image 27
Holt Avatar answered Feb 09 '23 06:02

Holt