2015-04-01 20 views
6

cerco di utilizzare il valore-inizializzazione per i membri con valore di inizializzazione per i costruttori (non so se ho davvero usare i buoni rapporti ...)uniforme e valore di inizializzazione

Quindi ... Quando ho definire:

struct A 
{ 
    int a_; 
}; 

sono in grado di utilizzare:

A a{5}; 
assert(m.a_==5); 

Tuttavia, se voglio usare l'inizializzatore elemento di rinforzo e di un costruttore di inizializzazione-list

struct B 
{ 
    int b_ {1}; 
}; 

Questo non viene compilato (C++ 14: http://ideone.com/MQ1FMU):

B b{2}; 

Ecco l'errore:

prog.cpp:19:7: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)' 
    B b{2}; 
    ^
prog.cpp:19:7: note: candidates are: 
prog.cpp:10:8: note: constexpr B::B() 
struct B 
     ^
prog.cpp:10:8: note: candidate expects 0 arguments, 1 provided 
prog.cpp:10:8: note: constexpr B::B(const B&) 
prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'const B&' 
prog.cpp:10:8: note: constexpr B::B(B&&) 
prog.cpp:10:8: note: no known conversion for argument 1 from 'int' to 'B&&' 

Qual è la differenza, concept-saggio? Mille grazie!

+0

Beh, pensavo che fosse perché "B" non era un aggregato, ma in realtà sembra soddisfare i requisiti per quanto posso dire. È semplicemente non banale. –

+1

Nota che "C++ 14" su Ideone.com è g ++ - 4.9.2, che non è compatibile con C++ 14 (come attestato da questo errore di compilazione!) – Casey

risposta

2

Nelle regole C++ 11, B non è un tipo aggregato. C++ 11 [dcl.init.aggr]/1:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no brace-or-equal-initializers for non-static data members (9.2), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

B ha solo un costruttore di default, e quindi non può essere inizializzato dal rinforzato-inizializzatore-list{2}.

C++ 14 consente di inizializzare iniziatori per membri di dati non statici in un aggregato. N4140 [dcl.init.aggr]/1:

An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.1), no private or protected non-static data members (Clause 11), no base classes (Clause 10), and no virtual functions (10.3).

Con semantica abbastanza straight-forward: campi per i quali non esiste inizializzatore specificato vengono inizializzati dal loro brace-o-uguale-inizializzatore eventuale e altrimenti inizializzato con {} [dcl.init.aggr]/7:

If there are fewer initializer-clauses in the list than there are members in the aggregate, then each member not explicitly initialized shall be initialized from its brace-or-equal-initializer or, if there is no brace-or-equal-initializer, from an empty initializer list (8.5.4).

Il vostro programma è quindi valida C++ 14 (DEMO). In sostanza, il divieto di inizializzatore brace-or-equal- in C++ 11 è stato un errore corretto in C++ 14.

+0

Grazie mille per la risposta dettagliata! Credo che avrei dovuto provare con un altro compilatore C++ 14 per essere sicuro ... – fp12

Problemi correlati