Using size of one array in another array
// sizeofarray.cpp
#include <iostream>
template <开发者_如何学Gotypename T,int N>
int size(T (&Array)[N])
{
return N;
}
int main()
{
char p[]="Je suis trop bon, et vous?";
char q[size(p)]; // (A)
return 0;
}
I heard that an array size in C++ must be a constant expression. So char q[size(p)]
is invalid, am I right? But I got no errors when I tried
g++ -Wall sizeofarray.cpp
Why?
Like Prasoon says, it's not a constant expression. For now, you can get a constant-expression value of the size of an array like this:
template <std::size_t N>
struct type_of_size
{
typedef char type[N];
};
template <typename T, std::size_t Size>
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]);
#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray))
Explanation here. You basically encode the size of the array into the size of a type, then get the sizeof
of that type, giving you:
char q[sizeof_array(p)];
I heard that an array size in C++ must be a constant expression.
Correct
So char q[size(p)] is invalid, am I right?
According to ISO C++, yes!
But I got no errors when I tried
g++ -Wall sizeofarray.cpp
That's because g++ supports VLA (Variable Length Array) as an extension.
In C++0x
there is constexpr
feature with the help of which you can write
constexpr int size(T (&Array)[N])
{
return N;
}
and then char q[size(p)]
would be legal.
EDIT : Also read this article [blog whatever]
I beg to differ with all the answers here. The code show is perfectly fine except for a minor issue (which is definitely not VLA)
template <typename T,int N>
int size(T (&Array)[N])
{
return N;
}
int main()
{
char p[]="Je suis trop bon, et vous?";
char q[sizeof(p)]; // (A), not sizeof and not size as in OP
return 0;
}
I was wondering that the result of the sizeof is always a const value, and hence the code should be fine.
The above code builds fine on VS 2010 and Comeau(strict mode)
$5.3.3/6- "The result is a constant of type size_t. [Note: size_t is defined in the standard header (18.1)."
I use g++ 4.4.3 and have the following alias so that I never forget to turn on the warnings:
$ alias g++
alias g++='g++ -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings'
If compiled with the above, there would be some warnings. Following steps show how different options show different warnings.
Compilation with no warning option does not show any warning
$ \g++ sizeofarray.cpp
Turning on -Wall
$ \g++ -Wall sizeofarray.cpp
sizeofarray.cpp: In function ‘int main()’:
sizeofarray.cpp:12: warning: unused variable ‘q’
Turning on -Wextra
$ \g++ -Wall -Wextra sizeofarray.cpp
sizeofarray.cpp: In function ‘int main()’:
sizeofarray.cpp:12: warning: unused variable ‘q’
sizeofarray.cpp: At global scope:
sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’:
sizeofarray.cpp:12: instantiated from here
sizeofarray.cpp:4: warning: unused parameter ‘Array’
Finally turning on -pedantic
to catch the real problem
$ \g++ -Wall -Wextra -pedantic sizeofarray.cpp
sizeofarray.cpp: In function ‘int main()’:
sizeofarray.cpp:12: warning: ISO C++ forbids variable length array ‘q’
sizeofarray.cpp:12: warning: unused variable ‘q’
sizeofarray.cpp: At global scope:
sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’:
sizeofarray.cpp:12: instantiated from here
sizeofarray.cpp:4: warning: unused parameter ‘Array’
精彩评论