By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,162 Members | 1,099 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,162 IT Pros & Developers. It's quick & easy.

Array template parameters

P: n/a
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

Jul 22 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
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.

Jul 22 '05 #2

P: n/a
"serock" <s.******@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.
Jul 22 '05 #3

P: n/a
Siemel Naran wrote in
news:oZ*******************@bgtnsc05-news.ops.worldnet.att.net in
comp.lang.c++:
"serock" <s.******@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/
Jul 22 '05 #4

P: n/a
"Rob Williscroft" <rt*@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.
Jul 22 '05 #5

P: n/a
"Rade" <no*************@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.
Jul 22 '05 #6

P: n/a
> 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
Jul 22 '05 #7

P: n/a
Siemel Naran wrote in
news:Z7*******************@bgtnsc05-news.ops.worldnet.att.net in
comp.lang.c++:
"Rob Williscroft" <rt*@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/
Jul 22 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.