Почему поле внутри локального класса не может быть статическим?

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 разрешено), а не для других типов данных. Это всего лишь один случай, который приходит мне на ум.

Ответы

Ответ 1

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

Edit:

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

foo.h

class A {
  static int dude;
};

foo.cpp

int A::dude = 314;

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

Иногда, не реализует, это правильное решение.

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

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

Один пример: Самый неприятный анализ.

Ответ 4

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

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

Ответ 5

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

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