Frage Mutieren eines int innerhalb einer constexpr-Funktion


Warum kann ich das tun:

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

Aber ich kann das nicht tun:

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

Meine Fragen sind:

  1. Wenn ich mutieren kann intWarum kann ich nicht mutieren? int Das ist innerhalb des Arrays?
  2. Ist dies eine Sprachbeschränkung (C ++ 14) oder ein Standard-Bibliotheksspezifikations-Problem? reference std::array<T, N>::operator[](size_t) ist derzeit nicht constexpr.

23
2017-08-09 10:03


Ursprung


Antworten:


Es ist eine Einschränkung der Standardbibliothek seit du kann Ändern Sie ein einfaches C-Array in a 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

Ausgabe

9

Wenn Sie hinzugefügt haben constexpr zu operator[] einer Implementierung von array, Sie könnten diesen Operator auch in einem verwenden constexpr.

DEMO


16
2017-08-09 10:16



Modifikation von Objekten im Inneren constexpr Funktionen wurde mit C ++ 14 eingeführt. Während jedoch z.B. ein Skalar durch eine Zuweisung ist in Ordnung, das Modifizieren eines Klassenobjekts durch eine Elementfunktion benötigt diese Elementfunktion immer noch constexpr. Und leider, wie du schon erwähnt hast, der Strom std::array Spezifikation deklariert nicht die nichtconst  operator[] wie constexpr.
Daher macht §7.1.5 / 5 Ihre Definition schlecht formuliert:

Für eine Nicht-Vorlage, nicht voreingestellt constexpr Funktion [...], falls nein   Argumentwerte existieren so, dass ein Aufruf der Funktion [...]   könnte ein ausgewerteter Unterausdruck eines Kernkonstantenausdrucks sein   (5.20), [...] das Programm ist schlecht gebildet; keine Diagnose erforderlich.

Sie können eine modernere Implementierung vorübergehend verwenden, wenn Sie voll sein möchten constexpr-ness. Z.B. Constainer::Array.


17
2017-08-09 10:30