Type Dependent Constant in Template Function

I want a static array in a template function, the length of which depends on the type with which the function specializes. My first attempt:

Title:

template<typename T> struct Length { const static size_t len; }; template<typename T> void func(){ static T vars[Length<T>::len]; // len not const. according to compiler! // ... } 

Original file:

 template<> const size_t Length<double>::len = 2; template<> const size_t Length<float>::len = 1; // ... 

However, g++ does not compile this and complains

error: storage size 'vars isnt constant

So what is the problem? I know that the size of a fixed-length array must be constant and known at compile time, but this seems to be the case here. When I write

 const size_t len = 2; void func(){ static double vars[len]; } 

It compiles without problems.

Question:

What is wrong with the code and what alternatives exist to achieve the desired behavior? I would not want to allocate memory at runtime ...

+5
source share
2 answers

For a const variable that will be considered a compile-time constant (formally, a constant expression), its value must be available at the point of use. This means that specialized definitions will have to go to the header file.

If this is done as soon as the member specializes, just like you, I believe that this will give you a multiple-definition error. You should be fine with specializing the entire class template and preserving the definition of the static inline member:

 template<typename T> struct Length; template <> struct Length<double> { static const size_t len = 2; }; 

As a side note, your program was initially invalid: explicit specialization must be declared before use. This means that you need to at least declare the len specialization in the header (or wherever you intend to use it).

+5
source

The following code compiles for me with g++ 4.6.3 and produces output

 2 1 

array.cpp :

 #include <cstddef> #include <iostream> template<typename T> struct Length { const static size_t len; }; template<typename T> void func(){ static T vars[Length<T>::len]; std::cout << (sizeof(vars) / sizeof(*vars)) << std::endl; } template<> const size_t Length<double>::len = 2; template<> const size_t Length<float>::len = 1; int main(){ func<double>(); func<float>(); } 
 $ make array g++ array.cpp -o array $ ./array 2 1 
+1
source

All Articles