Подтвердить что ты не робот

Почему в локальных классах допускаются не статические члены данных?

Какова причина того, почему члены 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):

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

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

Ответ 3

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

  abc.h

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

   int myClass::number = 314;

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

Ответ 4

По мере продвижения, у нас теперь есть С++ 11, и с этим вы можете определить переменные-члены интегральных констант в своих классах.

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

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

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

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