2014-11-04 11 views
10
#include <iostream> 
#include <array> 

int main(int argc, char **argv) { 
    constexpr const std::array<int, 2> arr {{ 0, 1 }}; 
    constexpr const int arr2[] = { 0, 1}; 

    static_assert(arr[0] == arr2[0], "asdf"); 
    static_assert(arr[1] == arr2[1], "asdfasdf"); 

    return 0; 
} 

Wenn kompiliert mit gcc 4.8.2 und 4.9.1g++ test.cpp --std=c++11 verwenden, gelingt es der Kompilierung. zusammengestellt Wenn mit clang 3.4 und 3.5clang++ test.cpp --std=c++11 jedoch verwenden, schlägt die Kompilierung:constexpr std :: Array mit static_assert

test.cpp:8:16: error: static_assert expression is not an integral constant expression 
     static_assert(arr[0] == arr2[0], "asdf"); 
         ^~~~~~~~~~~~~~~~~ 
test.cpp:8:16: note: non-constexpr function 'operator[]' cannot be used in a constant expression 

Also meine Frage ist, der Compiler ist „richtig“ im Sinne von mit C++ 11 konform zu sein? Und wenn clang richtig ist, warum ist dann std :: array operator[] nicht conexpr fähig? Ist das nicht eines der Dinge, die helfen sollte?

Antwort

9

Es sieht aus wie clang richtig ist, operator [] kein constexpr in C++ 11 ist, sondern ein constexpr in C++ 14

constexpr const_reference operator[](size_type pos) const; (since C++14) 

so mit -std=c++14 Kompilieren obwohl funktionieren sollte (see it live).

Im C++11 draft standard Abschnitt 23.3.2.1Vorlage Klasse Array Übersicht hat die folgenden für operator []:

reference operator[](size_type n); 
const_reference operator[](size_type n) const; 

während die C++14 draft standard hat folgendes:

reference operator[](size_type n); 
constexpr const_reference operator[](size_type n) const; 
^^^^^^^^^ 

aktualisieren

Draft-Standard N3485, der nach C++ 11 kam, enthält Verbesserungen zu C++ 11. Es enthält eine constexpr Version von operator []. Wenn dies Teil eines Fehlerberichts wäre, dann wäre gcc korrekt und dies erscheint plausibel unter Berücksichtigung clang 3.6.0 akzeptiert auch das Programm in C++ 11-Modus.

Update 2

fand ich das Dokument, das die Änderungen eingeführt, N3470 und da ich keine Fehlerberichte zu diesem speziellen Thema finden kann dann scheint dies wie eine Erweiterung und daher nicht Teil von C + sein sollte +11.

+0

In C++ 11 wurde es möglich, 'array :: operator [] const 'als' constexpr 'zu deklarieren, aber das Komitee kam erst in C++ 14 dazu. In C++ 14 wurde es möglich, array :: operator [] 'als" constexpr "zu deklarieren ... – Casey

+1

@Casey Ich habe das Dokument gefunden, das die Änderung in' N3485' einführte, ich fügte es meiner Antwort hinzu. Soweit ich weiß, wenn es als Defekt betrachtet wird, sollte es im C++ 11-Modus erlaubt sein, ansonsten nicht. Das Dokument verdeutlicht dies jedoch nicht. –

+1

Ich habe mich am meisten über den Standard lustig gemacht: Änderungen in der Bibliothek liegen oft hinter dem Kern zurück, weil Core Änderungen in letzter Minute vornehmen möchte, ohne der Bibliothek ausreichend Zeit zu geben, um zu reagieren. Ich glaube, dass die Ergänzungen "conetexpr" in N3470 eine Verbesserung darstellen, da der einzige Fehlerbericht für "array", der "constexpr" beinhaltet, [LWG DR 720] ist (http://www.open-std.org/jtc1/sc22) /wg21/docs/lwg-defects.html#720), und es beinhaltet nicht 'operator []'. – Casey