Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Определение члена-константы внутри/снаружи класса, есть ли разница? 
V
    Опции темы
zim22
Дата 11.8.2009, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Внутри класса не получается инициализировать константу значением функции.
Код

#include <cstdlib>

int fcn() { return rand(); }

struct Foo {
  static const int c = fcn(); // error C2057: expected constant expression
};


Если же вынести определение константы вне класса - то проблем нет.
Код

struct Foo {
  static const int c;
};
const int Foo::c = fcn(); 


Получается, что определение констант внутри класса является всего-лишь более ограниченной формой определения вне класса?
Код

struct Foo {
  static const int c = 5;
};

(т.е. внутри класса я должен константное выражение передать, а при инициализации вне класса - что угодно).


--------------------
PM MAIL   Вверх
azesmcar
Дата 11.8.2009, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



zim22

А вопрос в чем?
PM   Вверх
zim22
Дата 11.8.2009, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  11.8.2009,  16:42 Найти цитируемый пост)
А вопрос в чем?

Цитата(zim22 @  11.8.2009,  16:38 Найти цитируемый пост)
Получается, что определение констант внутри класса является всего-лишь более ограниченной формой определения вне класса?

уточню вопрос:
допустим у нас есть такой код:
Код

struct Foo {
  static const int c;
  int arr[c]; //  error C2057: expected constant expression
};

const int Foo::c = fcn();

Почему ошибка? ведь с - константа.


--------------------
PM MAIL   Вверх
azesmcar
Дата 11.8.2009, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

If a static data member is of const integral or const enumeration type, its declaration in the class
definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that
case, the member can appear in integral constant expressions. 
The member shall still be defined in a namespace
scope if it is used in the program and the namespace scope definition shall not contain an initializer.


Цитата(zim22 @  11.8.2009,  16:47 Найти цитируемый пост)
Почему ошибка? ведь с - константа. 

Тут ошибка потому, что
Цитата

In that case, the member can appear in integral constant expressions

это не тот случай.

Это сообщение отредактировал(а) azesmcar - 11.8.2009, 16:58
PM   Вверх
zim22
Дата 11.8.2009, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  11.8.2009,  16:52 Найти цитируемый пост)
and the namespace scope definition shall not contain an initializer

я нарушил стандарт, да?
***
нет. я его не нарушил.
всё это:
Цитата

If a static data member is of const integral or const enumeration type, its declaration in the class
definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that
case, the member can appear in integral constant expressions. The member shall still be defined in a namespace
scope if it is used in the program and the namespace scope definition shall not contain an initializer.

относилось к такому случаю:
Код

struct Foo {
  static const int c = 7;
  int arr[c];
};
const int Foo::c;


Это сообщение отредактировал(а) zim22 - 11.8.2009, 17:04


--------------------
PM MAIL   Вверх
azesmcar
Дата 11.8.2009, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(zim22 @  11.8.2009,  17:00 Найти цитируемый пост)
я нарушил стандарт, да? 

Ну, раз не компилируется smile 
Если инициализировать "на месте", это компайл-тайм константа, ею можно специализировать шаблоны, создавать массивы, а как вы предполагаете инициализировать константу рантайм и использовать ее в compile-time (создавать массив)?

Добавлено через 1 минуту и 54 секунды
Цитата(zim22 @  11.8.2009,  17:00 Найти цитируемый пост)
всё это:
относилось к такому случаю:

Да, и там описано что только в этом случае

Цитата(azesmcar @  11.8.2009,  16:52 Найти цитируемый пост)
In that
case, the member can appear in integral constant expressions. 



Это сообщение отредактировал(а) azesmcar - 11.8.2009, 17:05
PM   Вверх
zim22
Дата 11.8.2009, 17:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  11.8.2009,  17:04 Найти цитируемый пост)
а как вы предполагаете инициализировать константу рантайм и использовать ее в compile-time?

инициализировать константу рантайм получилось:
Код

#include <cstdlib>

int fcn() { return rand(); }
struct Foo {
  static const int c;
};
const int Foo::c = fcn(); 

а вот в компайл тайм использовать не получится... smile


--------------------
PM MAIL   Вверх
azesmcar
Дата 11.8.2009, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(zim22 @  11.8.2009,  17:07 Найти цитируемый пост)
инициализировать константу рантайм получилось:

инициализировать можно, но...тут ведь дело не в инициализации а в использовании
Код

int fcn()
{
    return 10;
}


int main()
{
    const int i = fcn();
    int c[i];
}

вот это ведь не будет работать? Что нужно чтобы это заработало?
Код

int fcn()
{
    return 10;
}


int main()
{
    const int i = 10;
    int c[i];
}

теперь i - константа времени компиляции, все работает.
Откуда во время компиляции, компилятор узнает о значении, которое будет ясно лишь на этапе выполнения. Т.е. как вы предполагаете использовать эту константу?

zim22 кажется понял. Вы забываете про то, что в C++ два вида констант
Константа времени выполнения и константа времени компиляции.

Добавлено
не так понял smile
Цитата(zim22 @  11.8.2009,  17:07 Найти цитируемый пост)
а вот в компайл тайм использовать не получится... smile 

прочитал как не получАется smile но все равно, оставлю пост.

Это сообщение отредактировал(а) azesmcar - 11.8.2009, 17:16
PM   Вверх
zim22
Дата 11.8.2009, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(azesmcar @  11.8.2009,  17:09 Найти цитируемый пост)
 Т.е. как вы предполагаете использовать эту константу?

я ещё не придумал smile
но преимущества есть. это ведь Константа! и изменять её значение мы не можем, после того, как она будет инициализирована.

Например такой код позволит нам самим устанавливать значение константы! а не зашивать её в программу.
Код

int fcn() { 
  int res; 
  std::cin >> res; 
  return res; 
}
struct Foo {
  static const int c;
};
const int Foo::c = fcn(); 



--------------------
PM MAIL   Вверх
azesmcar
Дата 11.8.2009, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(zim22 @  11.8.2009,  17:16 Найти цитируемый пост)
я ещё не придумал smile
но преимущества есть. это ведь Константа! и изменять её значение мы не можем, после того, как она будет инициализирована.

Я имел ввиду на этапе компиляции, а так, думаю применение найдется smile

PM   Вверх
mes
Дата 11.8.2009, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Вам поможет constexpr из грядущего стандарта, которая позволит явно разделить константы на два лагеря : readonly и constexpr.
http://en.wikipedia.org/wiki/C%2B%2B0x#Gen...ant_expressions

Это сообщение отредактировал(а) mes - 11.8.2009, 18:09


--------------------
PM MAIL WWW   Вверх
zim22
Дата 11.8.2009, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


depict1
****


Профиль
Группа: Завсегдатай
Сообщений: 2682
Регистрация: 15.1.2009
Где: Украина

Репутация: 29
Всего: 69



Цитата(mes @  11.8.2009,  17:40 Найти цитируемый пост)
Вам поможет constexpr из грядущего стандарта

супер!  smile 


--------------------
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0592 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.