Puede abarcar ser constexpr?


11

Todos los constructores de std :: span se declaran constexpr, sin embargo, parece que no puedo hacer que ninguno de ellos funcione en un contexto constexpr. Descomentar cualquiera de los constexpr a continuación dará como resultado un error de compilación.

#include <array>
#include <span>

int main()
{
    constexpr int carray[3] = { 0, 1, 2 };
    constexpr std::array<int, 3> array{ 0, 1, 2 };
    using S = std::span<const int, 3>;

    /*constexpr*/ S span1{ array.data(), 3 };
    /*constexpr*/ S span2{array.begin(), array.end()};
    /*constexpr*/ S span3{carray};
    /*constexpr*/ S span4{array};
}

De hecho, ¿es posible crear un tipo de intervalo constexpr, ya que parece que los constructores nunca pueden evaluarse en tiempo de compilación cuando tienen que inicializar un puntero o referencia?


Descomente los constexprs no los elimine.
— Andreas Loanjoe el

Está iniciando un período de tiempo de ejecución que quise inicializar un período de tiempo de constexpr
— Andreas Loanjoe

Doh No estoy seguro de por qué hice eso. no importa
— NathanOliver

raro, no veo por qué eso sería necesario el lapso sólo se vive dentro del ámbito local de todos modos ...
— Andreas Loanjoe

Respuestas:


13

No puede usar variables locales de funciones no estáticas en una expresión constante como esa. Necesita estabilidad de dirección y eso solo se logra mediante objetos estáticos. Modificando el código a

constexpr std::array<int, 3> array{ 0, 1, 2 };
constexpr int carray[3] = { 0, 1, 2 };

int main()
{
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

o

int main()
{
    static constexpr std::array<int, 3> array{ 0, 1, 2 };
    static constexpr int carray[3] = { 0, 1, 2 };
    using S = std::span<const int, 3>;

    constexpr S span1{ array.data(), 3 };
    constexpr S span2{array.begin(), array.end()};
    constexpr S span3{carray};
    constexpr S span4{array};
}

Le permite crear un constexpr std::span.


55
El alcance no es el problema. La duración del almacenamiento es. El local estático debería funcionar.
— eerorika

También funciona si todos son objetos locales de función dentro de una constexprfunción (sin explícito static). ¿Estos objetos tienen una duración predeterminada de almacenamiento estático o es algo diferente?
— n314159

@ n314159 No estoy seguro de si eso está permitido o si ha caído en el temido: si ninguna especialización de una función constexpr es una expresión constante central, la función está mal formada, no se requiere una cláusula de diagnóstico. [expr.const] / 10 solo permite variables estáticas.
— NathanOliver

@ n314159: No estoy seguro exactamente de lo que estás diciendo que funciona (o "funciona"), pero ten cuidado con la diferencia entre usar algo como una expresión constante en una función (constexpr o no) y usar algo para construir una constante expresión a través de una función constexpr.
— Davis Herring

Es posible que desee decir que los valores no estáticos (constantes) se pueden usar en expresiones constantes, pero no sus direcciones .
— Davis Herring
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.