Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type-dependent constant in template function

I want a static array in a templated function whose length depends on the type with which the function is specialized. My first attempt was:

Header:

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!
  // ...
}

Source 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 of ‘vars’ isn’t constant

So, what exactly is the problem here? I know that the size of a fixed-length array needs to be a constant and known on compile time, but that 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 which alternatives are there for achieving the desired behavior? I would not like to allocate the memory during runtime...

like image 290
piripiri Avatar asked Apr 11 '15 09:04

piripiri


People also ask

Which of the datatypes are supported by template?

Class Templates like function templates, class templates are useful when a class defines something that is independent of the data type. Can be useful for classes like LinkedList, BinaryTree, Stack, Queue, Array, etc. Following is a simple example of a template Array class.

What is dependent type in C++?

A function whose type of return value varies with its argument (i.e. there is no fixed codomain) is a dependent function and the type of this function is called dependent product type, pi-type (Π type) or dependent function type.

What is dependent name example?

A dependent name is a name that depends on the type or the value of a template parameter. For example: template<class T> class U : A<T> { typename T::B x; void f(A<T>& y) { *y++; } }; The dependent names in this example are the base class A<T> , the type name T::B , and the variable y .

What is template type parameter?

A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.


1 Answers

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

If done as just specialisations of the member, as you did, I believe that would give you a multiple-definition error. You should be fine with specialising the entire class template, and keeping the static member definition inline:

template<typename T>
struct Length;

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

As a side note, your program was originally invalid: an explicit specialisation must be declared before use. Which means you'd have to at least declare the specialisation of len in the header (or everywhere you intended to use it).

like image 178
Angew is no longer proud of SO Avatar answered Oct 04 '22 07:10

Angew is no longer proud of SO