Использование размера одного массива в другом массиве

// sizeofarray.cpp
#include <iostream>
template <typename 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;
}

Я слышал, что размер массива в C ++ должен быть постоянным выражением. Итак, char q[size(p)] недействителен, я прав? Но у меня не было ошибок, когда я попробовал

 g++ -Wall sizeofarray.cpp

Почему?


person Ideone    schedule 30.09.2010    source источник
comment
q[sizeof(p)] в порядке, вы, наверное, имели в виду q[size(p)]. Обратите внимание, что последнее станет действительным в C ++ 0x (если вы объявите size как constexpr).   -  person avakar    schedule 30.09.2010
comment
Проблема заключается в «размере», а не в «sizeof». Смотрите мой пост.   -  person Chubsdad    schedule 30.09.2010
comment
Попробуйте параметры компилятора -pedantic или -std = c ++ 98 ;-)   -  person sellibitze    schedule 30.09.2010


Ответы (4)


Как и Прасун говорит, это не константа выражение. На данный момент вы можете получить значение константного выражения размера массива следующим образом:

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))

Объяснение здесь. Вы в основном кодируете размер массива в размер типа, а затем получаете sizeof этого типа, что дает вам:

char q[sizeof_array(p)];
person GManNickG    schedule 30.09.2010

Я слышал, что размер массива в C ++ должен быть постоянным выражением.

Правильный

Итак, char q [size (p)] недействителен, я прав?

Согласно ISO C ++, да!

Но у меня не было ошибок, когда я попробовал

g ++ -Wall sizeofarray.cpp

Это потому, что g ++ поддерживает VLA (Variable Length Array) в качестве расширения.

В C++0x есть функция constexpr с помощью что ты можешь написать

constexpr int size(T (&Array)[N])
{
  return N;
}

и тогда char q[size(p)] будет законным.

РЕДАКТИРОВАТЬ: также прочтите это статья [что угодно в блоге]

person Prasoon Saurav    schedule 30.09.2010
comment
конечно sizeof - это постоянное выражение (по крайней мере, для не-vla, которого в стандартном C ++ даже нет)? - person nos; 30.09.2010

Я прошу не согласиться со всеми ответами здесь. Показ кода прекрасен, за исключением незначительной проблемы (которая определенно не относится к 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; 
} 

Мне было интересно, что результатом sizeof всегда является значение const, и, следовательно, код должен быть в порядке.

Приведенный выше код отлично подходит для VS 2010 и Comeau (строгий режим).

$ 5.3.3 / 6- "Результатом является константа типа size_t. [Примечание: size_t определено в стандартном заголовке (18.1)."

person Chubsdad    schedule 30.09.2010
comment
Я думаю, он, вероятно, имел в виду char q[size(p)]. Я внес необходимые исправления в ОП. - person Prasoon Saurav; 30.09.2010

Я использую g ++ 4.4.3 и имею следующий псевдоним, чтобы никогда не забывать включать предупреждения:

$ alias g++
alias g++='g++ -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings'

Если скомпилировать с указанным выше, будут некоторые предупреждения. Следующие шаги показывают, как разные параметры отображают разные предупреждения.

Компиляция без предупреждения не показывает никаких предупреждений

$ \g++ sizeofarray.cpp 

Включение -Wall

$ \g++ -Wall sizeofarray.cpp
sizeofarray.cpp: In function ‘int main()’:
sizeofarray.cpp:12: warning: unused variable ‘q’

Включение -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’

Наконец, включив -pedantic, чтобы выявить настоящую проблему

$ \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’
person Arun    schedule 30.09.2010