2016-04-08 15 views
5

Per questo codice:funzione membro constexpr non statica con il costruttore non constexpr (gcc, clang differire)

struct S 
{ 
    S(int m): m(m) {} 
    constexpr int f() const { return m; } 

    int m; 
}; 

int main() { S s(1); } 

viene compilato senza avvisi o errori clang 3.6, 3.7 e 3.8 con -std=c++14. Ma in g ++ 5.x si verificano i seguenti errori:

main.cpp:4:19: error: enclosing class of constexpr non-static member function 'int S::f() const' is not a literal type 
    constexpr int f() const { return m; } 
      ^
main.cpp:1:8: note: 'S' is not literal because: 
struct S 
     ^
main.cpp:1:8: note: 'S' is not an aggregate, does not have a trivial default constructor, and has no constexpr constructor that is not a copy or move constructor 

Quale compilatore è corretto e perché?

Ho esaminato i requisiti in C++ 14 [dcl.constexpr]/3 che dice che per una funzione constexpr "ciascuno dei suoi tipi di parametri deve essere un tipo letterale", ma quella sezione non menziona esplicitamente le funzioni membro e non dice se l'implicito *this conta come parametro ai fini di questa clausola.

+0

Dubito che una funzione membro di questo tipo possa essere effettivamente utile, perché sicuramente non può essere calcolata in fase di compilazione, non è vero? Quindi direi che la diagnostica di gcc è più corretta. – user3159253

+0

Per essere sicuro di aver appena provato un build GCC su tronco, è ancora rotto. – user657267

+0

@ user657267 OK. Forse non è una priorità alta; come sottolinea user3159253, questo codice non è molto utile perché la valutazione di 'f()' sarà in realtà non-constexpr, anche in clang, perché 'S' non è un tipo letterale (quindi' constexpr S s (1); 'non è permesso). –

risposta

6

Si tratta di un difetto di base che è stato fissato per C++ 14

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1684

Clang è stato patchato

https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/6jM8M8FUs30

C'è un tracker per GCC, ma non assomiglia a nessuno lo ha ancora risolto

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66297

+0

Non si applica solo alle funzioni membro _static_? – user3159253

+0

I commenti sul DR suggeriscono che il comportamento precedente era destinato a membri non statici e questa modifica era intesa a correggere il membro statico ... ma la modifica effettiva sembra essere applicabile a entrambi. La trama si infittisce? –

+0

In effetti il ​​link alla mailing list spiega che il comitato ha deciso di rimuoverlo intenzionalmente anche per non-static, in una modifica rispetto a quanto originariamente raccomandato dalla DR –

Problemi correlati