Quelle est cette folle syntaxe C ++ 11 ==> struct: bar {} foo {} ;?

168

Qu'est-ce que cela pourrait signifier en C ++ 11?

struct : bar {} foo {};
Courses de légèreté en orbite
la source
Intéressant, l'avez-vous trouvé utile pour quelque chose? Je suppose que c'est une astuce pour générer des instances uniques fortement typées (types marqués).
alfC
@alfC: Pas particulièrement utile, non
Courses de légèreté en orbite

Réponses:

262

Tout d'abord, nous allons prendre un UDT abstrait standard (type défini par l'utilisateur):

struct foo { virtual void f() = 0; }; // normal abstract type
foo obj;
// error: cannot declare variable 'obj' to be of abstract type 'foo'

Rappelons également que nous pouvons instancier l'UDT en même temps que nous le définissons:

struct foo { foo() { cout << "!"; } };          // just a definition

struct foo { foo() { cout << "!"; } } instance; // so much more
// Output: "!"

Combinons les exemples, et rappelons que nous pouvons définir un UDT qui n'a pas de nom :

struct { virtual void f() = 0; } instance; // unnamed abstract type
// error: cannot declare variable 'instance' to be of abstract type '<anonymous struct>'

Nous n'avons plus besoin de la preuve de l'UDT anonyme, nous pouvons donc perdre la fonction virtuelle pure. Renommer également instanceen foo, il nous reste:

struct {} foo;

Se rapprocher.


Maintenant, que se passerait-il si cet UDT anonyme provenait d'une base?

struct bar {};       // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof

Enfin, C ++ 11 introduit des initialiseurs étendus , de sorte que nous pouvons faire des choses déroutantes comme ceci:

int x{0};

Et ça:

int x{};

Et, enfin, ceci:

struct : bar {} foo {};

Il s'agit d'une structure non nommée dérivant de bar, instanciée en tant que foo avec un initialiseur vide.

Courses de légèreté en orbite
la source
11
Je sais que les commentaires négatifs sur un langage de programmation devraient être évités, et c'est peut-être un peu hors sujet ici. Mais je ne comprends pas pourquoi C ++ 0x devient un langage encore plus complexe que C ++. Qui veut ça? Quels sont les avantages d'un langage de programmation de plus en plus crypté? Cette déclaration est à mon humble avis un autre exemple de cela. J'utilise C ++ depuis de nombreuses années et j'ai encore des difficultés à maîtriser ce langage.
Giorgio
26
@Giorgio: Pourquoi est-ce un problème? Qu'est-ce qui vous fait peur exactement? La construction décrite est un cas marginal autorisé par le langage et qui découle naturellement de ses concepts de base, il n'y a rien de mal à cela. C'est aussi d'une utilité très limitée. Vous n'aurez jamais à l'utiliser. Cependant, il est syntaxiquement logique et ne heurte ni n'entre en conflit avec quoi que ce soit. Alors, pourquoi serait-ce un argument contre un langage, en particulier celui qui est exceptionnellement bien conçu?
Kerrek SB
13
@Giorgio - ce qui est merveilleux, c'est que la situation est exactement le contraire; c ++ 0x ajoute de nombreuses fonctionnalités puissantes tant attendues sans être cryptiques ou trop laides; vous voulez cryptique? - Découvrez Perl. Cet exemple ici ne s'approche nulle part du titre de cryptique.
Gene Bushuyev
18
@Kerrek SB Je pense que C ++ (et maintenant C ++ 0x) a tout simplement trop de concepts différents et apprendre la syntaxe et la sémantique est difficile. Chaque programmeur (je suis l'un d'entre eux) finit par utiliser un sous-ensemble du langage car il y a trop de façons différentes de faire la même chose. Je ne pense pas que C ++ soit bien conçu. Il existe de nombreuses fonctionnalités ad hoc et certaines choses fondamentales comme un mécanisme robuste de module (import / export) manquent (toujours en utilisant l'ancien #include de C). Je pense que l'effort de C ++ 0x devrait viser à rendre C ++ plus petit et plus facile à utiliser, pas plus grand.
Giorgio
31
@Giorgio: Pour être honnête, un tel effort devrait travailler sur la reconstruction du C ++ à partir de zéro, c'est-à-dire la création d'un nouveau langage . Et cela a été fait ... plusieurs fois.
Courses de légèreté en orbite
106

Cela définit:

  • une structure anonyme,
  • qui est dérivé publiquement de bar
  • qui ( anonymously) ne définit rien d'autre que de quoi il dérivebar
  • et enfin, une instance, appelée "foo" est créée,
  • avec une liste d'initialiseurs vide

struct : bar {} foo {};
Frunsi
la source