Почему статические члены-члены не разрешены в локальных классах? - PullRequest
23 голосов
/ 17 ноября 2011

В чем причина того, что static const члены не могут существовать в локальных классах?Это выглядит как довольно глупое ограничение.

Пример:

void foo() {
  struct bar {
    int baz() { return 0; }   // allowed
    static const int qux = 0; // not allowed?!?
  };
}

struct non_local_bar {
  int baz() { return 0; }   // allowed
  static const int qux = 0; // allowed
};

Цитата из стандарта (9.8.4):

Локальный класс не должен иметь статическийчлены данных.

Ответы [ 4 ]

22 голосов
/ 17 ноября 2011

Из стандартного раздела 9.4.2:

Если член статических данных имеет константный интеграл или константный тип перечисления, его объявление в определении класса может указывать инициализатор константы, который должен бытьинтегральное постоянное выражение.В этом случае член может появляться в виде целочисленных константных выражений в своей области видимости. Член по-прежнему должен быть определен в области имен , если он используется в программе, а определение области имен не должно содержать инициализатора.

По существу, локальные классы не имеют связии статическим членам данных требуется связывание.

Поскольку невозможно определить статический член данных локального класса в области пространства имен (объявление с инициализатором не является определением), они не разрешены, независимо от того,они имеют константный интегральный тип или нет.На первый взгляд может показаться, что компилятор должен просто иметь возможность встроить значение, но что произойдет, если вы попытаетесь получить доступ к указателю на член?С классами в пространстве имен вы бы просто получили ошибку компоновщика, но локальные классы не имеют никакой связи.

Я предполагаю, что теоретически они могли бы просто позволить вам использовать статические константные интегральные типы в локальных классах, пока они толькоиспользуется в интегральных константных выражениях, но это, вероятно, просто возложило бы слишком много бремени на разработчиков стандартов и поставщиков компиляторов, чтобы их можно было отличить из-за очень небольшой практической ценности;локальные статические переменные доступны из локальных классов, поэтому использование локальных статических констант должно быть таким же хорошим.

4 голосов
/ 17 ноября 2011

Я не думаю, что есть причина. Нормальные статические камеры данных запрещены, потому что нет возможности определить их после объявления.

Также не забывайте, что вы можете создать локальную константную переменную вне класса., Которую вы можете использовать внутри класса, если вы только читаете его значение (то есть, пока вы не берете .its.address).

2 голосов
/ 17 ноября 2011

Статические члены класса должны быть определены в глобальной области видимости, например,

  abc.h

   class myClass {
   static int number;
  };
     abc.cpp

   int myClass::number = 314;

Теперь, поскольку область действия внутри void abc (int x) не является глобальной, нет области для определения статического члена.

0 голосов
/ 15 мая 2014

По мере развития дела у нас теперь есть C ++ 11, и с его помощью вы можете определять переменные-члены целочисленных констант в ваших классах.

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

Это работает, когда вы компилируете с C ++ 11.Обратите внимание, что ключевое слово static не используется.При компиляции с включенными оптимизациями эти переменные, скорее всего, будут оптимизированы.Однако при отладке они появляются в вашей структуре как обычные члены-переменные.

Обратите внимание, однако, что размер класса / структуры будет по-прежнему включать эту переменную.Так что здесь, скорее всего, 4 байта для переменной FOO.

Однако в большинстве случаев классы, определенные в функции, будут полностью оптимизированы, так что это отличный способ работы (хорошие 50% моегоклассы имеют такие переменные члены!)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...