tags:

views:

205

answers:

3

So I just learned via a compiler error that in-class initialization of arrays is invalid (why?). Now I would like to have some arrays initialized in a template class, and unfortunatly the contents depend on the template parameter. A condensed testcase looks like this:

template<typename T>
struct A {
    T x;
    static const int len = sizeof(T);         // this is of course fine
    static const int table[4] = { 0, len, 2*len, 3*len };    //this not
}

Any idea how to pull out the constant array?

EDIT: Added the 'int's.

+5  A: 

Just as you'd do it without templates; put the initialization outside the class' declaration:

template<class T>
const int A<T>::table[4] = { 0, len, 2*len, 3*len };
Georg Fritzsche
Now I#m wondering why I just didn't try it that way. Too early in the morning, I guess.
drhirsch
I guess everybody has this moments :)
Georg Fritzsche
A: 

template <typename T, int index>
struct Table {
   static const len = sizeof(T);        
   static const value = len*index;
};
Alexey Malistov
index isn't a constant value, so unfortunatly this won't work. Additionally, in reality the table contains 128 bit sized constants which can't be efficiently computed using a multiplication. This is the reason I used a table in the first place
drhirsch
+2  A: 
 class Y
  { 
     const int c3 = 7; // error: not static 
     static int c4 = 7; // error: not const static const
     float c5 = 7; // error not integral
  };

So why do these inconvenient restrictions exist? A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

for more detail read : How do I define an in-class constant?

sat
To clarify: the same is true for `int` values. Even `static int const` may *not* be defined inline inside the class. What looks like a definition in fact isn’t one. This can easily be tested by trying to get the address of that static member: this will fail, since the member is never defined, only declared.
Konrad Rudolph
Thanks, now I see the difference. In fact, the "static const int" were "#define LEN (sizeof(T))" in an earlier version.
drhirsch