Почему поле внутри локального класса не может быть статичным? - PullRequest
13 голосов
/ 26 мая 2011
void foo (int x)
{
  struct A { static const int d = 0; }; // error
}

Кроме ссылки из стандарта, есть ли мотив для этого запретить static поле внутри внутреннего класса?

error: field `foo(int)::A::d' in local class cannot be static

Редактировать : Однако, static разрешены функции-члены.У меня есть один вариант использования для такого сценария.Предположим, я хочу, чтобы foo() вызывался только для POD, тогда я могу реализовать его следующим образом:

template<typename T>
void foo (T x)
{
  struct A { static const T d = 0; }; // many compilers allow double, float etc.
}

foo() должен проходить только для POD (если разрешено static), а не для других типов данных,Это только один случай использования, который приходит мне в голову.

Ответы [ 5 ]

5 голосов
/ 26 мая 2011

Магнус Ског дал реальный ответ: статический член данных - это просто декларация; объект должен быть определен в другом месте, в области пространства имен, а определение класса не отображается в области пространства имен.

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

class Local
{
    static int& static_i()
    {
        static int value;
        return value;
    }
};

Это предоставляет вам точно такую ​​же функциональность, за счет используя синтаксис функции для доступа к нему.

4 голосов
/ 26 мая 2011

Потому что никто не видел в этом необходимости?

[править] : статические переменные должны быть определены только один раз, как правило, вне класса (кроме встроенных). Разрешение их внутри локального класса потребовало бы разработки способа их определения. [/ править]

Любая функция, добавленная к языку, имеет стоимость:

  • это должно быть реализовано компилятором
  • он должен поддерживаться в компиляторе (и может содержать ошибки, даже в других функциях)
  • он живет в компиляторе (и, следовательно, может вызвать некоторое замедление, даже если он не используется)

Иногда не реализует функция является правильным решением.

Локальные функции и классы уже добавляют сложность языку для небольшой выгоды: их можно избежать с помощью static функций и безымянных пространств имен.

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

Один пример: Самый волнующий разбор .

4 голосов
/ 26 мая 2011

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

Редактировать:

Извините за то, что я бездельник и просто выбрасываю вещи :) Чтобы быть немного более точным,Статические члены класса должны быть определены в глобальной области видимости, например,

foo.h

class A {
  static int dude;
};

foo.cpp

int A::dude = 314;

Теперь, поскольку область видимости внутриvoid foo (int x) не является глобальным, нет области для определения статического члена.Надеюсь, это было немного яснее.

0 голосов
/ 26 мая 2011

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

Если бы мне пришлось угадывать, почему существует ограничение, я бы сказал, что это как-то связано с тем, что компилятору трудно понять, когда выполнять статическую инициализацию.Документы по стандартам C ++ могут дать более формальное обоснование.

0 голосов
/ 26 мая 2011

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

Имя foo()::A::d не подходит для определения компоновщиком, так как он должен найти определение статического члена?Что если в функции baz () есть другая структура A?

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