| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"Rade" |
| Date: |
05 Dec 2004 10:19:15 AM |
| Object: |
Array template parameters |
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
.
|
|
| User: "Siemel Naran" |
|
| Title: Re: Array template parameters |
05 Dec 2004 02:44:19 PM |
|
|
"Rade" <no.such.address@btinternet.com> wrote in message news:covce2$e84
#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<array, 4>;
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.
.
|
|
|
|
| User: "serock" |
|
| Title: Re: Array template parameters |
05 Dec 2004 01:04:48 PM |
|
|
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];
-----------------------------------------------------------------
Static member definition should be separated from its declaration.
.
|
|
|
| User: "Siemel Naran" |
|
| Title: Re: Array template parameters |
05 Dec 2004 02:13:08 PM |
|
|
"serock" <s.rock.e@gmail.com> wrote in message
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];
-----------------------------------------------------------------
Static member definition should be separated from its declaration.
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.
.
|
|
|
| User: "Rob Williscroft" |
|
| Title: Re: Array template parameters |
05 Dec 2004 02:16:48 PM |
|
|
Siemel Naran wrote in
news:oZJsd.93415$7i4.16403@bgtnsc05-news.ops.worldnet.att.net in
comp.lang.c++:
"serock" <s.rock.e@gmail.com> wrote in message
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];
-----------------------------------------------------------------
Static member definition should be separated from its declaration.
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.
--
http://www.victim-prime.dsl.pipex.com/
.
|
|
|
| User: "Siemel Naran" |
|
| Title: Re: Array template parameters |
05 Dec 2004 02:24:25 PM |
|
|
"Rob Williscroft" <rtw@freenet.co.uk> wrote in message
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.
.
|
|
|
| User: "Rob Williscroft" |
|
| Title: Re: Array template parameters |
05 Dec 2004 03:16:42 PM |
|
|
Siemel Naran wrote in
news:Z7Ksd.93447$7i4.30400@bgtnsc05-news.ops.worldnet.att.net in
comp.lang.c++:
"Rob Williscroft" <rtw@freenet.co.uk> wrote in message
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.
--
http://www.victim-prime.dsl.pipex.com/
.
|
|
|
|
|
|
|
| User: "Rade" |
|
| Title: Re: Array template parameters |
05 Dec 2004 03:03:24 PM |
|
|
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
.
|
|
|
|
|

|
Related Articles |
|
|