2016-08-21 3 views
5

Beachten Sie Folgendes:Regeln für Anonymous Aggregates

#include <type_traits> 

struct MyType { 
    int val; 
    MyType(void) = default; 
    MyType(int v) : val(v) {} 
}; 
static_assert(std::is_standard_layout<MyType>::value,"Implementation error!"); 
static_assert(std::is_trivial<MyType>::value,"Implementation error!"); 
static_assert(std::is_pod<MyType>::value,"Implementation error!"); 

struct Wrapper { 
    struct { 
     MyType t; 
    }; 
}; 

MSVC, Clang und Intel C++ alle es gut kompilieren. Aber g++4.9 foo.cpp -std=c++11 sagt mir:

14 : error: member 'MyType Wrapper::<anonymous struct>::t' with constructor not allowed in anonymous aggregate
MyType t;
^
Compilation failed

Beachten Sie, dass die static_assert s sicherzustellen, dass MyType ist ein standard layout Typ, ein trivial type, und darüber hinaus tatsächlich POD ist (beachten Sie, dass nach C++ 11, PODs sind erlaubt Konstrukteuren zu haben).


Ich konnte nichts autoritatives darüber finden, welche Typen in anonymen Strukturen erlaubt sind. Was ich gefunden habe (meistens hier auf SO), legt nahe, dass ein POD-Typ ausreichend ist. Offensichtlich ist es nicht.

Meine Frage: Wenn ein POD-Typ tatsächlich nicht ausreicht, um in einer anonymen Struktur zu sein, was ist ist ausreichend? Oder ist GCC, da es sich von allen anderen Compilern unterscheidet, ein Problem mit GCC?

+2

[Kompiliert nicht in Clang] (http://melpon.org/wandbox/permlink/EymdTe46Ss7Sn1xA); ist nicht gut ausgebildet C++. –

+0

@KerrekSB: Es [kompiliert] (http://melpon.org/wandbox/permlink/4S88COP93nH4zyeV), wenn Sie die anonyme Struktur in eine reguläre unbenannte Struktur ändern. Zugegeben, ich bin mir nicht sicher, ob der OP [den Unterschied versteht.] (Http://stackoverflow.com/q/14248044/734069) Während ich denke, seine Frage ist hauptsächlich über das Verhalten von komplexen Typen in unbenannten Strukturen, der OP muss dies klären, bevor wir fortfahren können. –

+0

@ NicolBolas Ich verstehe jetzt besser die Terminologie. Die Frage ist jedoch immer noch, unter welchen Bedingungen-GCC-akzeptiert-den-Code.Offensichtlich ist es nicht erforderlich - da nur unbenannte Strukturen bisher Standard sind - aber ich bin überrascht, dass ein POD-Typ nicht ausreicht. – imallett

Antwort

5

Soweit Standards betroffen sind, sind anonyme Strukturen ein C-Feature. Sie sind von keinem C++ - Standard erlaubt.

Ich konnte detaillierte GCC-Dokumentation über ihre Erweiterung nicht finden, um die Funktion in C++ bereitzustellen. Was ich wenig gefunden habe, ist here, aber diese Seite scheint nur die Erweiterung für C zu beschreiben (vor C11 war diese Funktion nicht Standard).

My question: If being a POD type is actually insufficient for being in an anonymous structure,

Es scheint in der Tat nicht ausreichend. Die Fehlermeldung erklärt ganz klar, dass ein (nicht-trivialer) Konstruktor eine Klasse von einem anonymen Aggregat (Struktur) disqualifiziert. Ein POD würde dies nur vor C++ 11 garantieren.

Da es scheint, wenig Dokumentation für die Erweiterung zu sein, und da anonyme Strukturen ein C-Feature sind, bin ich versucht zu schätzen, dass ein solches Aggregat keine C++ - Funktionen verwenden darf. Ich glaube, dass die Definition eines POD vor C++ 11 eine solche Anforderung erfüllt.

Ein schneller Test scheint mit meiner Hypothese übereinzustimmen. Wenn Sie den Konstruktor entfernen, wird das Programm mit der aktivierten Erweiterung kompiliert. Wenn Sie das Strukturelement benennen (den Typ auf unbenannte zu fördern), wird das Programm gut formuliertes Standard-C++ und kompiliert.

Or perhaps, since GCC is differing from all other compilers, is this a problem with GCC?

Da das ist die Art, wie sie es implementiert haben, ist es sehr wahrscheinlich kein Problem mit ihnen. Es könnte ein Problem für jemanden sein, der ohne Modifikation ein Nicht-Standard-Programm kompilieren möchte, das für einen anderen Compiler geschrieben wurde. Dies ist ein Problem mit nicht standardmäßigen Sprachfunktionen im Allgemeinen.