Требования
Я хочу значение constexpr
(т.е. константу времени компиляции), вычисленную из функции constexpr
. И я хочу, чтобы оба эти области были охвачены пространством имен класса, то есть статическим методом и статическим членом класса.
Первая попытка
Я сначала написал это (мне) очевидным образом:
class C1 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar = foo(sizeof(int));
};
g++-4.5.3 -std=gnu++0x
говорит следующее:
error: ‘static int C1::foo(int)’ cannot appear in a constant-expression
error: a function call cannot appear in a constant-expression
g++-4.6.3 -std=gnu++0x
жалуется:
error: field initializer is not constant
Вторая попытка
Хорошо, подумал я, возможно, мне нужно переместить вещи из класса. Поэтому я попробовал следующее:
class C2 {
constexpr static int foo(int x) { return x + 1; }
constexpr static int bar;
};
constexpr int C2::bar = C2::foo(sizeof(int));
g++-4.5.3
будет компилировать это без жалоб. К сожалению, в моем другом коде используются циклы for
на основе диапазона, поэтому у меня должно быть не менее 4,6. Теперь, когда я смотрю ближе к списку поддержки, кажется, что constexpr
потребуется также 4.6. И с g++-4.6.3
я получаю
3:24: error: constexpr static data member ‘bar’ must have an initializer
5:19: error: redeclaration ‘C2::bar’ differs in ‘constexpr’
3:24: error: from previous declaration ‘C2::bar’
5:19: error: ‘C2::bar’ declared ‘constexpr’ outside its class
5:19: error: declaration of ‘const int C2::bar’ outside of class is not definition [-fpermissive]
Это звучит очень странно для меня. Как вещи "отличаются в constexpr
" здесь? Мне не хочется добавлять -fpermissive
, поскольку я предпочитаю, чтобы мой другой код был тщательно проверен. Перемещение реализации foo
вне тела класса не имело видимого эффекта.
Ожидаемые ответы
Может кто-нибудь объяснить, что здесь происходит? Как я могу достичь того, что я пытаюсь сделать? Меня в основном интересуют ответы следующих типов:
- Способ выполнения этой работы в gcc-4.6
- Наблюдение, что более поздние версии gcc могут иметь дело с одной из версий правильно
- Указатель на спецификацию, согласно которой, по крайней мере, одна из моих конструкций должна работать, так что я могу обмануть разработчиков gcc, чтобы заставить их работать.
- Информация о том, что то, что я хочу, невозможно в соответствии со спецификациями, предпочтительно с некоторым подтверждением относительно обоснования этого ограничения.
Другие полезные ответы также приветствуются, но, возможно, они не будут приняты так же легко.