2014-11-04 19 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; 
} 

quando viene compilato con gcc 4.8.2 e 4.9.1 utilizzando g++ test.cpp --std=c++11, la compilazione riesce. quando si compila con clang 3.4 e 3.5 utilizzando clang++ test.cpp --std=c++11 tuttavia, la compilazione fallisce:constexpr std :: array con 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 

Quindi la mia domanda è, quale compilatore è "giusto" nel senso di essere compatibile con C++ 11? E, se clang è corretto, allora perché lo standard std :: array operator[] non supporta constexpr? Non è forse una delle cose che lo std::array avrebbe dovuto aiutare a risolvere?

risposta

9

Sembra clang è corretto, non è un operator [] constexpr in C++ 11, ma è un constexpr in C++ 14

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

così la compilazione con -std=c++14 dovrebbe funzionare anche se (see it live).

Nella sezione C++11 draft standard23.3.2.1Classe panoramica template gamma ha i seguenti per operator []:

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

mentre il C++14 draft standard ha il seguente:

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

Aggiornamento

La bozza dello standard N3485 fornita dopo C++ 11 contiene correzioni e miglioramenti a C++ 11. Contiene una versione constexpr di operator []. Se questo faceva parte di un rapporto sui difetti, allora gcc sarebbe corretto e questo sembra plausibile considerando che clang 3.6.0 accetta anche il programma in modalità C++ 11.

Update 2

Ho trovato il documento che ha introdotto le modifiche, N3470 e siccome non riesco a trovare alcun rapporto difetti su questo problema specifico, allora questo sembra come un accessorio e quindi non dovrebbe essere parte di C + +11.

+0

In C++ 11, è diventato possibile dichiarare 'array :: operator [] const' come' constexpr', ma il comitato non è riuscito a farlo fino a C++ 14. In C++ 14, è diventato possibile dichiarare 'array :: operator []' come 'constexpr' ... – Casey

+1

@Casey Ho trovato il documento che ha introdotto la modifica in' N3485', l'ho aggiunto alla mia risposta. Per quanto ho capito se fosse considerato un difetto dovrebbe essere permesso in modalità C++ 11, ma per il resto no. Il documento non chiarisce questo però. –

+1

Principalmente mi sono divertito allo standard: le modifiche alle librerie sono spesso in ritardo rispetto al core, perché al core piace apportare modifiche all'ultimo minuto senza fornire alla biblioteca il tempo sufficiente per reagire. Credo che le aggiunte di 'constexpr' in N3470 siano un miglioramento, dal momento che l'unico rapporto sui difetti per' array' che implica 'constexpr' è [LWG DR 720] (http://www.open-std.org/jtc1/sc22 /wg21/docs/lwg-defects.html#720), e non coinvolge 'operator []'. – Casey

Problemi correlati