Mutar un int dentro de una función constexpr


¿Por qué puedo hacer esto:

constexpr auto i_can() {
   int a = 8;
   a = 9;
   //...
}

Pero no puedo hacer esto:

constexpr auto i_cannot() {
    std::array<int, 10> arr{};
    //I cannot
    arr[5] = 9;
}

Mis preguntas son:

  1. Si puedo mutar un int, ¿por qué no puedo mutar un int que está dentro de la matriz?
  2. ¿Es esto una limitación del lenguaje (C++14) o un problema de especificaciones de biblioteca estándar? reference std::array<T, N>::operator[](size_t) no es actualmente constexpr.
Author: Jamal, 2015-08-09

2 answers

Es una limitación de la biblioteca estándar ya que puede modificar una matriz C simple en un constexpr:

#include <iostream>

constexpr auto demo()
{
   int arr[10] = {};
   arr[5] = 9;
   return arr[5];
}

int main()
{
    static_assert(demo() == 9, "");
    std::cout << demo() << std::endl;
    return 0;
}   

DEMO

Salida

9

Si agregaste constexpr a operator[] de una implementación de array, también podrías usar este operador dentro de un constexpr.

DEMO

 16
Author: m.s.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-09 14:31:56

La modificación de objetos dentro de funciones constexpr se ha introducido con C++14. Sin embargo, mientras que modificar, por ejemplo, un escalar por una asignación está bien, modificar un objeto de clase a través de una función miembro todavía necesita que esa función miembro sea constexpr. Y desafortunadamente, como usted mencionó, la especificación actual std::array no declara la no-const operator[] como constexpr.
Por lo tanto, §7.1.5 / 5 hace que su definición mal formada:

Para una función que no sea de plantilla, no predeterminada constexpr [function], si no los valores de los argumentos existen de tal manera que una invocación de la función […] podría ser una subexpresión evaluada de una expresión constante central (5.20), [ ... ], el programa está mal formado; no se requiere diagnóstico.

Puede usar temporalmente una implementación más moderna si desea constexpr-ness completo. E. g. Constainer::Array.

 17
Author: Columbo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-09 11:05:37