Array template parameters

R

Rade

Please have a look at the following program:

#include <iostream>

template <const int array[], size_t index>
class ArrayIndex
{
public:
static const int value = array[index];
};

extern const int array[] = { 1, 2, 3, 4, 5 };

int main()
{
std::cout <<
ArrayIndex<array, 0>::value << "," <<
ArrayIndex<array, 1>::value << "," <<
ArrayIndex<array, 2>::value << "," <<
ArrayIndex<array, 3>::value << "," <<
ArrayIndex<array, 4>::value;
}

Output is, on my C++ compiler (VS 2003): 0,0,0,0,0 while I'd expect that the
output is 1,2,3,4,5. What actually does the C++ Standard say about this? In
other words, is the above program correct and if it is, what should be its
output with a standard-compliant compiler ? Moreover, if the program is
correct, is the expression 'array[index]' within the ArrayIndex class
regarded as a constant expression ?

(note that I had to declare the array with 'extern', which shouldn't be
necessary by the Standard, as this array has external linkage, anyway.
However, the compiler issues an error if I don't do this. So I have reasons
to suspect that the compiler is not standard-compliant).

Regards,
Rade
 
S

serock

template <const int array[], size_t index>
class ArrayIndex
{
public:
static const int value;
};

template <const int array[], size_t index>
const int ArrayIndex<array, index>::value = array[index];
 
S

Siemel Naran

serock said:
template <const int array[], size_t index>
class ArrayIndex
{
public:
static const int value;
};

template <const int array[], size_t index>
const int ArrayIndex<array, index>::value = array[index];

This is not required for static const integral types (int, char, bool, long,
short). I think the OP's code is legal, though my version of g++ and
Borland both complain.
 
R

Rob Williscroft

Siemel Naran wrote in
in
comp.lang.c++:
serock said:
template <const int array[], size_t index>
class ArrayIndex
{
public:
static const int value;
};

template <const int array[], size_t index>
const int ArrayIndex<array, index>::value = array[index];

This is not required for static const integral types (int, char, bool,
long, short). I think the OP's code is legal, though my version of
g++ and Borland both complain.

The problem is that the initializer "array[ index ]" *isn't* a
compile time constant (intergral constant expression).

IOW, the out of class initialization is required.

Rob.
 
S

Siemel Naran

Rob Williscroft said:
Siemel Naran wrote in
This is not required for static const integral types (int, char, bool,
long, short). I think the OP's code is legal, though my version of
g++ and Borland both complain.

The problem is that the initializer "array[ index ]" *isn't* a
compile time constant (intergral constant expression).

IOW, the out of class initialization is required.

Do you have a quote from the standard? I agree that if if 'array' has type
"int *" then array[3] is not an integral constant, but if it has type "int
const *" then array[3] should be a constant so long as array itself is
constant, which is the case because it is extern const.

In any case, I made the initialization out of line for g++ to compile it,
and I still witness the original behavior that it prints "0,0,0,0,0,"
instead of "1,2,3,4,5,". Strange. Yet when I force the instantiation of
the specific classes by using template class, it does work. Stranger.
 
S

Siemel Naran

Rade said:
#include <iostream>

template <const int array[], size_t index>
class ArrayIndex
{
public:
static const int value = array[index];
};

extern const int array[] = { 1, 2, 3, 4, 5 };

int main()
{
std::cout <<
ArrayIndex<array, 0>::value << "," <<
ArrayIndex<array, 1>::value << "," <<
ArrayIndex<array, 2>::value << "," <<
ArrayIndex<array, 3>::value << "," <<
ArrayIndex<array, 4>::value;
}

Output is, on my C++ compiler (VS 2003): 0,0,0,0,0 while I'd expect that the
output is 1,2,3,4,5.

This is quite strange. I added statements to force the compiler to
instantiate the ArraynIndex classes, and it works now, at least on g++
2.95.2-6. Add the five lines (without >) to your program and see if it
works.
extern const int array[] = { 1, 2, 3, 4, 5 };

template class ArrayIndex<array, 0>;
template class ArrayIndex<array, 1>;
template class ArrayIndex<array, 2>;
template class ArrayIndex<array, 3>;
template class ArrayIndex said:
int main()

What actually does the C++ Standard say about this? In
other words, is the above program correct and if it is, what should be its
output with a standard-compliant compiler ? Moreover, if the program is
correct, is the expression 'array[index]' within the ArrayIndex class
regarded as a constant expression ?

Seems to me array[index] is an integral expression because array has type T
const *const, but don't know what the standard says.
(note that I had to declare the array with 'extern', which shouldn't be
necessary by the Standard, as this array has external linkage, anyway.
However, the compiler issues an error if I don't do this. So I have reasons
to suspect that the compiler is not standard-compliant).

Const objects have internal linkage by default, so the extern is necessary.
 
R

Rade

Static member definition should be separated from its declaration.

OK, it's better now, but does C++ language require it, or the requirement
comes from Microsoft ?

As far as I know, one should be able to define static consts inside the
class as well as outside, as long as they are initialized by a constant
expression. That's why I asked about whether array[index] is regarded as a
constant expression in this context. If it is constant, then my code should
work (but it doesn't). If it is not constant, then the compiler should have
warned me that I was trying to initialize a static const within a class with
a nonconstant expression (but it hasn't). Am I right ?

Rade
 
R

Rob Williscroft

Siemel Naran wrote in
in
comp.lang.c++:
Rob Williscroft said:
Siemel Naran wrote in
This is not required for static const integral types (int, char,
bool, long, short). I think the OP's code is legal, though my
version of g++ and Borland both complain.

The problem is that the initializer "array[ index ]" *isn't* a
compile time constant (intergral constant expression).

IOW, the out of class initialization is required.

Do you have a quote from the standard?

5.19 & 5.2.1

Rob.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,184
Messages
2,570,978
Members
47,561
Latest member
gjsign

Latest Threads

Top