Można użyć wyraźny szablonu konkretyzacji dodatkowego członka statycznego, którego konstruktor dba o wypełnienie wpisy:
template<int length>
class myClass{
public:
static int array[length];
typedef enum{LENGTH=length} size_;
struct filler
{
filler(void)
{
for(int i=0;i<LENGTH;++i)
array[i]=i+1;
}
};
static filler fill_;
};
// of course, the line[s] below now do work as intended.
template<int length>
int myClass<length>::array[length];
//static member definition
template<int length>
typename myClass<length>::filler myClass<length>::fill_;
//explicit template instantiation
template myClass<5>::filler myClass<5>::fill_;
int main(void)
{
for(int i=0;i<myClass<5>::LENGTH;++i)
cout<<myClass<5>::array[i]<<endl;
return 0;
}
OR, ponieważ podobny (prawdopodobnie lepsze) rozwiązanie zostało już przedstawione powyżej przez Benoit, oto szablon rekurencyjna wersja, po prostu dla zabawy:
//recursive version:
template<int length>
class myClass{
public:
static int array[length];
typedef enum{LENGTH=length} size_;
static void do_fill(int* the_array)
{
the_array[LENGTH-1]=LENGTH;
myClass<length-1>::do_fill(the_array);
}
struct filler
{
filler(void)
{
/*for(int i=0;i<LENGTH;++i)
array[i]=i+1;*/
do_fill(array);
}
};
static filler fill_;
};
//explicit specialization to end the recursion
template<>
class myClass<1>{
public:
static int array[1];
typedef enum{LENGTH=1} size_;
static void do_fill(int* the_array)
{
the_array[LENGTH-1]=LENGTH;
}
};
//definition of the explicitly specialized version of the array
//to make the linker happy:
int myClass<1>::array[1];
// of course, the line below does not work as intended.
template<int length>
int myClass<length>::array[length];
//static member definition
template<int length>
typename myClass<length>::filler myClass<length>::fill_;
//explicit template instantiation
template myClass<5>::filler myClass<5>::fill_;
int main(void)
{
for(int i=0;i<myClass<5>::LENGTH;++i)
cout<<myClass<5>::array[i]<<endl;
return 0;
}
teraz różne kompilatory obsługują różne poziomy szablonu rekursji (a technika ta jest kompilator drogie) tak, staranne ...„Here Be Dragons” ;-)
Aha, jeszcze jedno, nie trzeba na nowo zdefiniować tablicę w wyspecjalizowanych wersji myClass, więc można pozbyć instancji array [1]:
//explicit specialization to end the recursion
template<>
class myClass<1>{
public:
typedef enum{LENGTH=1} size_;
static void do_fill(int* the_array)
{
the_array[LENGTH-1]=LENGTH;
}
};
Zadałem podobne pytanie jakiś czas temu: http://stackoverflow.com/questions/2850646/fill-container-with-template-parameters. Ale z 'std :: tr1 :: array' zamiast tej tablicy w stylu C ... – phlipsy