мой вопрос на самом деле: почему S :: size не является константным выражением? Я прочитал 5.19 (константное выражение) несколько раз и не обнаружил, что там упоминается случай, когда S :: size не является константным выражением.

читал немного о реализации стандартной библиотеки CLang, и это немного смущает меня на const и constexpr.

template<class _Tp, _Tp __v>
struct integral_constant
{
    static constexpr _Tp value = __v;
};

template<class _Tp, _Tp __v>
const _Tp integral_constant<_Tp, __v>::value;

Что меня смущает, так это то, что он использует constexpr внутри определения класса и const снаружи. Мой вопрос, это разрешено? И при каких условиях const и constexpr могут использоваться взаимозаменяемо? Конечно, функции contexpr не могут применяться к const, поэтому я имею в виду данные const и данные constexpr.

Я прочитал какой-то стандартный черновик и предложение вhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf, но это заставляет меня чувствовать себя более запутанным. Итак, у меня есть еще несколько вопросов,

В N2235 четко указано, что данные const не обязательно являются константами времени компиляции, см. Следующий пример:

struct S {
    static const int size;
};
const int limit = 2 * S::size; // dynamic initialization
const int S::size = 256;

и constexpr должен решить эту проблему, поэтому, по крайней мере, в этой ситуации constexpr не допускается, как показано ниже,

struct S {
    static const int size;
};
constexpr int limit = 2 * S::size; // shall be error in my understanding
const int S::size = 256;

Однако, прочитав черновик стандарта C ++ N3225, я нигде не вижу явно заявленного, что приведенный выше пример вызовет ошибку. В частности, из 7.1.5 / 9,

Спецификатор constexpr, используемый в объявлении объекта, объявляет объект как const. Такой объект должен иметь буквальный тип и должен быть инициализирован. Если он инициализируется вызовом конструктора, конструктор должен быть конструктором constexpr, и каждый аргумент конструктора должен быть константным выражением. этот вызов должен быть постоянным выражением (5.19). В противном случае каждое полное выражение, которое появляется в его инициализаторе, должно быть константным выражением.

Следовательно, если constexpr int limit = 2 * S :: size; неверно, то S :: size не должно быть константным выражением, тогда из 5.19 (константное выражение) я нигде не вижу стандартного запрета 2 * S :: size в приведенном выше примере, чтобы не быть константным выражением.

Кто-нибудь может указать на то, что я упустил из виду? Большое спасибо.

Ответы на вопрос(2)

Ваш ответ на вопрос