class A
{
public:
static const int _size_is;
static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
//Почему???
};
const int A::_size_is=100;
int A::array[_size_is];
Ну она константу требует на этапе компиляции, типа 1,2, ..... (В общем число конкретное)
Единственное, что можно сделать #define _SIZE_ = 4
static int array[_SIZE_]; , хотя это почти тоже самое, что и просто число
А>class A
А>{
А>public:
А>static const int _size_is; //(*)
А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>//Почему???
А>};
А>const int A::_size_is=100;
А>int A::array[_size_is];
Потому что (*) — это объявление некоторого константного объекта типа "int".
В C++ есть двойственность в отношении констант. С одной стороны, это — именованные литералы (т.е. значения, которые можно подставлять в выражения), а с другой стороны — это просто квалификатор доступа к переменным, наряду с volatile.
В объявлении класса константа — это всегда переменная, защищенная от модификации.
Чтобы обойти проблему, пиши так:
class A
{
enum { _size_is = 123 };
...
};
В данном случае _size_is — это именованный литерал некоторого целочисленного типа.
Здравствуйте, Stas Chistyakov, Вы писали:
SC>Ну она константу требует на этапе компиляции, типа 1,2, ..... (В общем число конкретное) SC>Единственное, что можно сделать #define _SIZE_ = 4 SC>static int array[_SIZE_]; , хотя это почти тоже самое, что и просто число
Ну почему же... Можно и без #define:
/*
Можно так
*/class A
{
public:
static const int _size_is = 100;
static int array[_size_is];
};
const int A::_size_is;
int A::array[_size_is];
/*
А можно и вот так
*/class A
{
public:
enum { _size_is = 100 };
static int array[_size_is];
};
int A::array[_size_is];
/*
И еще так
*/class A
{
public:
static const int _size_is;
static int array[];
};
const int A::_size_is = 100;
int A::array[_size_is];
А>class A
А>{
А>public:
А>static const int _size_is;
А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>// Размер массива должен быть известен - вот почему
// а статическая переменная к этому не обязывает
// ;)
А>};
А>const int A::_size_is=100;
А>int A::array[_size_is];
А>
const int _size_is =100;
class A
{
public:
int array[_size_is];
};
дешево и сердито
если же для каждого экземпляра нужен свой размер массива, то такой подход не катит — ну и не надо
проще добавить в конструктор параметр размер массива, и выделять его линамически либо руками , либа используя встроенный класс , например std::vector
Здравствуйте, <Аноним>, Вы писали:
А>Привет!!!
А> А>
А>class A
А>{
А>public:
А>static const int _size_is;
А>static int array[_size_is]; //Здесь ошибка!!! error C2057: expected constant expression
А>//Почему???
А>};
ИМХО, так как массив тоже static, то время жизни и момент инициализации у них одинаковые. Гарантии что константа будет проинициализированна раньше чем массив нет.
А>const int A::_size_is=100;
А>int A::array[_size_is];
А>
Здравствуйте, Дмитрий Наумов, Вы писали:
ДН>ИМХО, так как массив тоже static, то время жизни и момент инициализации у них одинаковые. Гарантии что константа будет проинициализированна раньше чем массив нет.
Это только ИМХО.
Статические объекты в одной единице компиляции всегда инициализируются в порядке взаимных зависимостей.
Причина — в другом, а именно — в нелитеральности выражения (т.е. компилятор не может его вычислить сам).
Аналогично коду
static const size_t len = strlen("hello");
static char buf[len+1];
Выдает 5. Поэтому я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни
Здравствуйте, DemAS, Вы писали:
К>>Аналогично коду К>>
К>>static const size_t len = strlen("hello");
К>>static char buf[len+1];
К>>
К>>Сколько байт должен выделить компилятор? А .
DAS> ... я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни
В данном случае компилятор должен знать, сколько памяти нужно для buf. Но strlen — библиотечная функция, а не ключевое слово языка C++. Компилятор не может знать, что делает эта функция и что она возвращает.
А еще можно написать свою функцию strlen...
Здравствуйте, DemAS, Вы писали:
К>>Причина — в другом, а именно — в нелитеральности выражения (т.е. компилятор не может его вычислить сам).
DAS> Извини, что вмешиваюсь в беседу двух умных людей, но уж больно хочется узнать, что такое нелитеральность ?
Литеральность (лат+рус) — буквальность. Литерал — это (в вольной трактовке) значение, определенное своим написанием... Блин, да как же это сказать-то?!
Все числа ( 0, 1, 2.345, ... ) — это литералы.
Строки в явном написании ( "hello" ) — тоже литералы.
Элементы перечисления (enum) — замещают целые числа — тоже.
Имена функций и переменных — по сути, их адреса — тоже можно считать литералами.
Выражения, составленные только из литералов — по индукции — тоже литеральные.
Вызовы функций — не литеральны, так как компилятор не "знает", что делает данная функция (особенно, если она определена в другом модуле, и ее нельзя инлайнить),
А в отношении константных переменных (const some_type var = NNN) есть двойственность.
С одной стороны, компилятор "знает", что это значение никогда не изменится (будет равно NNN) — и может им пользоваться. Но, с другой стороны, это все-таки переменная, размещенная в памяти, со своим адресом (ее, кстати, можно изменить с помощью const_cast).
const double pi_1 = 3.14159265358; // литерал
/////////extern const double pi_2; // константная переменная
...
const double pi_2 = 3.14159263658;
void hack_pi_2()
{
const_cast<double>(pi_2) = exp(1); // вот такое заподло :)
}
/////////const double pi_3 = atan(1)*4; // константная переменная;
// значение будет присвоено незадолго до входа в main()
К>>Аналогично коду
К>>static const size_t len = strlen("hello");
К>>static char buf[len+1];
К>>Сколько байт должен выделить компилятор? А .
DAS> Вот это: DAS>
DAS> Выдает 5. Поэтому я ожидал, что в твоем примере компилятор выделит 6 байт под массив char-ов. И почему это не компилится я так и не пойму. Если не сложно, поясни