mezclando el uso de constexpr y const?

Leí un poco de la implementación CLang de la biblioteca estándar y me confunde un poco const y 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;

Lo que me confunde es que está usando constexpr dentro de la definición de clase y const afuera. Mi pregunta es, ¿está permitido? ¿Y bajo qué situación const y constexpr se pueden usar indistintamente? Por supuesto, las funciones constexpr no pueden aplicarse a const, así que estoy hablando de datos const y datos constexpr.

Leí un borrador estándar y la propuesta enhttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2235.pdf, pero me hace sentir más confuso. Entonces tengo algunas preguntas más,

En N2235, establece claramente que no se garantiza que los datos constantes sean constantes de tiempo de compilación; consulte el siguiente ejemplo:

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

y se supone que constexpr resuelve esto, así que al menos en esta situación, constexpr no está permitido como se indica a continuación,

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

Sin embargo, después de leer el borrador estándar C ++ N3225, no veo en ninguna parte que se indique explícitamente que el ejemplo anterior cause un error. Particularmente, desde 7.1.5 / 9,

Un especificador constexpr utilizado en una declaración de objeto declara el objeto como constante. Tal objeto tendrá un tipo literal y se inicializará. Si se inicializa mediante una llamada de constructor, el constructor será un constructor constexpr y cada argumento al constructor será una expresión constante. esa llamada será una expresión constante (5.19). De lo contrario, cada expresión completa que aparece en su inicializador será una expresión constante.

Por lo tanto, si constexpr int limit = 2 * S :: size; es inválido, entonces S :: size no debe ser una expresión constante, luego de 5.19 (expresión constante), no veo en ninguna parte que el estándar no permita 2 * S :: size en el ejemplo anterior para que no sea una expresión constante.

¿Alguien puede señalar algo que haya pasado por alto? Muchas gracias.

Respuestas a la pregunta(2)

Su respuesta a la pregunta