2015-11-20 15 views
10

In C++ 14:Differenza tra T t <x} e T t = {x} per tipo integrale o di enumerazione?

Per qualsiasi integrale o censimento tipo T e per qualsiasi espressione expr:

C'è mai una differenza tra:

struct S { T t { expr }; }; 

e

struct S { T t = { expr }; }; 

Aggiornamento:

ho avuto modo di [dcl.init.list]p3b5 che dice:

If the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element.

Credo che questa citazione vale sia per -list-inizializzazione diretta e copia-list-inizializzazione.

Quindi penso che la risposta sia no, non c'è differenza.

+1

Perché dovrebbe essere ..? –

risposta

5

Se si dà un'occhiata a direct initialization e copy initialization riferimenti, troverete le stesse parole:

if T is a non-class type, standard conversions are used, if necessary, to convert the value of other to the cv-unqualified version of T

quindi non ci dovrebbe essere alcuna differenza. La differenza di queste inizializzazioni si applica solo per i tipi di classe: copia di inizializzazione fa non considerano explicit costruttori e explicit operatori di conversione definiti dall'utente, inizializzazione diretta fa. I tipi di enumerazione e integrale non hanno nessuno di essi.

Edit:
@ᐅ Johannes Schaub - litb ᐊ answered a relative question to this one (solo parentesi, invece di parentesi graffe) e ha fatto riferimento 8.5/14 con una formulazione simile (sottolineatura mia):

The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below. If the entity being initialized does not have class type, the expression-list in a parenthesized initializer shall be a single expression.

non riuscivo a trovare la controparte {} nella norma, o. Spero che questo sia abbastanza argomenti per supportare lo non c'è differenza risposta.

+0

Il tuo link parla di parentesi, non di parentesi. Non è chiaro che gli stessi argomenti valgano qui. –

+0

Pensavo che la prima metà della mia risposta fosse abbastanza. Spero ancora che ci sia una coerenza tra gli effetti tra '()' vs '=()' e '{}' vs '= {}'. – LogicStuff

+1

Bene, '{}' vs '= {}' è coerente con le aspettative dell'utente, non con '()' vs '=()'; Considera: 'volatile int x = 42; char a (char (x)); char b = (char (x)); char c {char (x)}; char d = {char {x}}; ' –

1
  1. struct S {T t { expr };}; è un inizializzatore membro di dati non-statico che non utilizza il segno di uguale.
  2. struct S{T t = { expr };}; è un inizializzatore di dati di dati non statici che utilizza il segno di uguale.

Il primo caso è un diretta-list-inizializzazione mentre il secondo è un copia-list-inizializzazione.

La differenza tra -list-inizializzazione diretta e copia-list-inizializzazione è che per il primo caso entrambi esplicitamente costruttori e non esplicite sono considerati, mentre per il secondo unico non esplicito i costruttori possono essere chiamati.

Per chiarire, si consideri il seguente esempio:

struct Foo { 
    int i; 
    explicit Foo(int i_) : i(i_) {} 
}; 

struct Bar { 
    Foo f {1}; 
}; 

Live Demo

In questo esempio Foo ha un costruttore explicit e Bar diretto inizializza suo membro f di tipo Foo. Il codice di esempio compila bene poiché per l'inizializzazione diretta sono considerati entrambi i costruttori explicit e non-explicit.

Ora modifichiamo l'esempio trasformando l'inizializzatore del membro dati non statici senza utilizzare il segno di uguale, ovvero un caso di inizializzazione di elenchi diretti in un inizializzatore di un membro di dati non statici con l'uso del segno di uguale, che è un caso di inizializzazione della lista di copia.

struct Foo { 
    int i; 
    explicit Foo(int i_) : i(i_) {} 
}; 

struct Bar { 
    Foo f = {1}; 
}; 

Live Demo

Ora l'esempio di cui sopra non compila ed emette un errore:

error: chosen constructor is explicit in copy-initialization

Questo è previsto perché, come già accennato in copia-list-inizializzazione unico non-esplicito i costruttori possono chiamare.

Ora per gli enumeratori e altri tipi di integrale, la differenza visualizzata sopra non si applica (vale a dire, non sono coinvolti costruttori). In quanto tale, le due affermazioni (cioè, [1] e [2]) sarebbero equivalenti.

Ma per completezza, consente di prendere in considerazione i seguenti esempi:

enum class Foo {A, B, C}; 

struct Bar { 
    Foo f{Foo::A}; 
}; 

e

enum class Foo {A, B, C}; 

struct Bar { 
    Foo f = {Foo::A}; 
}; 

Entrambi gli esempi compilare bene.

Considera anche i seguenti esempi:

struct Bar { 
    int i {1}; 
}; 

e

struct Bar { 
    int i = {1}; 
}; 

Entrambi gli esempi anche compilare bene.

+1

"Compila bene" e "nessuna differenza di effetti collaterali" non sono dichiarazioni equivalenti. – Orient

+0

L'ammontare della compilazione serve per illustrare che per i tipi integrati la differenza menzionata non si applica. Di conseguenza, per il tipo integrato non c'è differenza negli effetti collaterali. – 101010

Problemi correlati