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...
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.
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.
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 .
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.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With