2011-12-24 16 views
37

C11 supporta strutture anonime, in questo modo:Perché C++ 11 non supporta le strutture anonime, mentre C11 lo fa?

struct Foo 
{ 
    struct 
    { 
     size_t x, y; 
    }; 
}; 
struct Foo f; 
f.x = 17; 
f.y = 42; 

Fondamentalmente, i membri di tale struct sono trattati come se fossero membri del racchiude struct o union (ricorsivamente, se la struttura racchiude in sé era anonima).

Qual è stata la logica del C++ 11 che non include anche strutture anonime? Sono di utilità non comune (per lo più all'interno dei sindacati, per eliminare la digitazione di un identificatore per il struct), certamente. Ma sembrano un'aggiunta abbastanza ovvia alle specifiche (e una già implementata da molti compilatori) che sicuramente devono essere state discusse, almeno per preservare la compatibilità con lo standard C11. Allora perché non sono stati aggiunti?

+12

Non sono d'accordo con il voto che questa domanda non sia costruttiva. Anche le domande più delicate vanno bene. – GManNickG

+6

__ In pratica, la maggior parte dei compilatori C++ 11 supporta anche strutture anonime. Li ho usati sia in MSVC++ (da sempre) che con il compilatore Cll 11 di llvm di Apple. – bobobobo

+0

MinGW supporta anche strutture/unioni anonime. –

risposta

42

Poco sforzo è stato fatto per mantenere la compatibilità tra C++ e C man mano che le due lingue si evolvono. Si noti che gli array di stack di lunghezza variabile sono in C dal 1999, ma non sono stati inclusi in C++ 11. Mentre generalmente non introducono cose che si contraddicono a vicenda, il comitato C++ non si sta esattamente piegando all'indietro per assicurarsi che C++ 11 sia compatibile con le versioni di C oltre C89.

Inoltre, questa funzione sarebbe piuttosto complessa in C++, perché uno struct non è altro che uno class. E una struttura/classe anonima dovrebbe avere tutte le caratteristiche di una normale struct/class, sì? Altrimenti, che senso ha averlo?

Cosa significherebbe costruire un senza nome struct? Come definiresti il ​​costruttore? Qualcosa di semplice come:

struct Foo 
{ 
    struct 
    { 
     size_t &x; 
    }; 
}; 

non è semplicemente possibile perché l'interno struct non ha un costruttore. E non c'è modo di specificarne uno. A struct non è possibile creare i membri di un altro struct al suo interno.

per qualcosa di simile:

struct Foo 
{ 
    size_t outer; 
    struct 
    { 
     void SomeFunc(); 
     size_t x; 
    }; 
}; 

Cosa this puntatore non SomeFunc ottenere? Quale sarebbe il tipo di this, il tipo senza nome e senza nome? Come definiresti anche SomeFunc al di fuori della struttura? Il nome di SomeFunc non può essere Foo::SomeFunc, perché SomeFunc vive in un ambito interno.

È troppo complesso per il C++ da gestire. E certamente non ne vale la pena abbastanza per preoccuparsi di aggiungere questa complessità.

+14

Questo ha un senso ragionevole, anche se posso immaginare restrizioni che lo renderebbero del tutto sensato: POD, nessun metodo (ereditato o meno) e pienamente pubblico, penso, risolva i problemi che sollevi. Mi sembra anche che le unioni anonime introducano già molti di questi problemi, quindi i problemi non mi sembrano "troppo complessi", se non nel senso di una scarsa capacità di risolverli. –

+11

"Cosa significherebbe costruire una struttura senza nome? Come definiresti il ​​costruttore?". La stessa cosa può essere chiesta per un'unione senza nome. Anche i sindacati possono avere costruttori. –

+0

Inoltre, la maggior parte di ciò che si ottiene in C11 da strutture anonime è possibile anche ottenere dall'ereditarietà. I sindacati anonimi sarebbero più utili, ma come Nicol sottolinea che l'intera funzionalità è inadatta per il C++. –

3

Per svolgere l'avvocato del diavolo, le dichiarazioni di classe e struct vengono utilizzate spesso per racchiudere dichiarazioni di tipo specifiche della classe.

typedef struct { 

} name; 

pertanto dovrebbe essere consentito.

Pertanto

struct { 

} 

dovrebbe essere pure.

Tuttavia, se consideriamo questa come una semplice dichiarazione all'interno del namespace di una classe, non ci sarebbe alcun modo per accedere all'interno della struttura.

Perché struct! = Spazio dei nomi in C, C può creare regole come accedere a una struttura anonima attraverso la struttura circostante.

Per C++ per consentire ciò, sarebbe necessario un caso speciale in questa situazione, che complicherebbe la risoluzione dei nomi.

Ovviamente, l'avvocato del diavolo è il diavolo - C in realtà ha fatto questo. Aggiunge un ulteriore livello alla risoluzione dei nomi - se non riesci a trovare il nome in uno stant, controlla i membri anonimi della struct. Il che è un po 'magico, in un modo che posso vedere fastidiosi i membri del comitato C++.

Solleva anche delle domande: se è possibile accedere a una struttura anonima tramite la sua classe genitore, a proposito di strutture anonime in uno spazio dei nomi.

Naturalmente, se proprio vuoi sapere, basta chiedere a Stroustrup - risponde alle e-mail.

+0

Questo non può essere il motivo giusto --- le unioni anonime * sono * supportate (anche in C++ 98!), Ma le strutture anonime non lo sono? Se questo fosse il motivo, allora anche le unioni anonime non dovrebbero essere supportate, poiché condividono lo stesso spazio dei nomi delle strutture. –

+0

Trovo divertente il "piccolo magico". A me sembra più simile "Questo non è C. Decidiamo, neener-neener." – 6502

+0

C++ supporta già le unioni anonime e gli spazi dei nomi anonimi in cui i contenuti si rovesciano, come se fossero dichiarati in linea nell'ambito esterno. Le strutture anonime completano quel trio (particolarmente utile nella programmazione grafica). In un altro aspetto, C++ 11 va anche oltre C e supporta gli spazi dei nomi in linea (anche quando è denominato, non solo anonimo). http://stackoverflow.com/questions/11016220/what-are-inline-namespaces-for –

-2

E che questo funziona in C++ 11

struct A 
{ 
    int someVariable; 
}; 

struct B : public A 
{ 
    int someOtherVariable; 
}; 

Usarlo come:

B structB; 
structB.someVariable = 5; 
structB.someOtherVariable = 6; 

Questo mi ha aiutato a risolvere un problema simile.

Problemi correlati