O que é essa sintaxe maluca do C ++ 11 ==> struct: bar {} foo {} ;?

168

O que isso poderia significar em C ++ 11?

struct : bar {} foo {};
Raças de leveza em órbita
fonte
Interessante, você achou útil para alguma coisa? Eu acho que é um truque para gerar instâncias únicas de tipos fortes (tipos marcados).
AlfC #
@alfC: Não particularmente útil, não
Leveza raças na órbita

Respostas:

262

Primeiro, tomaremos um resumo UDT (tipo definido pelo usuário) padrão:

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

Lembremos também que podemos instanciar a UDT ao mesmo tempo que a definimos:

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

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

Vamos combinar os exemplos e lembrar que podemos definir uma UDT sem nome :

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

Não precisamos mais da prova sobre a UDT anônima, para que possamos perder a função virtual pura. Também renomeando instancepara foo, ficamos com:

struct {} foo;

Chegando perto.


Agora, e se essa UDT anônima derivasse de alguma base?

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

Finalmente, o C ++ 11 introduz inicializadores estendidos , para que possamos fazer coisas confusas como esta:

int x{0};

E isto:

int x{};

E, finalmente, isso:

struct : bar {} foo {};

Esta é uma estrutura sem nome derivada de bar, instanciada como foo com um inicializador em branco.

Raças de leveza em órbita
fonte
11
Eu sei que comentários negativos sobre uma linguagem de programação devem ser evitados, e talvez seja um pouco fora de tópico aqui. Mas não entendo por que o C ++ 0x está se tornando uma linguagem ainda mais complexa do que o C ++. Quem quer isso? Quais são as vantagens de uma linguagem de programação que está se tornando cada vez mais enigmática? Esta declaração é IMHO, mais um exemplo disso. Uso C ++ há muitos anos e ainda tenho dificuldades para dominar essa linguagem.
Giorgio
26
@Giorgio: Por que isso é um problema? O que exatamente te assusta? A construção descrita é um caso marginal que é permitido pela linguagem e segue naturalmente de seus conceitos principais, não há nada de errado com ela. Também é de utilidade muito limitada. Você nunca precisará usá-lo. No entanto, é sintaticamente lógico e não colide ou entra em conflito com nada. Então, por que esse seria um argumento contra uma linguagem, especialmente uma que é excepcionalmente bem projetada?
21411 Kerrek SB
13
@Giorgio - a parte maravilhosa é que a situação é exatamente o oposto; O c ++ 0x está adicionando muitas instalações poderosas aguardadas sem ser enigmático ou muito feio; você quer enigmático? - confira Perl. Este exemplo aqui nem chega perto do título de enigmático.
Gene Bushuyev 15/08
18
@Kerrek SB Eu acho que o C ++ (e agora o C ++ 0x) tem muitos conceitos diferentes e aprender a sintaxe e a semântica é difícil. Cada programador (eu sou um deles) acaba usando um subconjunto da linguagem porque existem muitas maneiras diferentes de fazer a mesma coisa. Eu não acho que o C ++ seja bem projetado. Existem muitos recursos ad-hoc e algumas coisas fundamentais, como um mecanismo robusto de módulo (importação / exportação), estão ausentes (ainda usando o #include antigo de C). Eu acho que o esforço do C ++ 0x deve ter como objetivo tornar o C ++ menor e mais fácil de usar, não maior.
Giorgio
31
@Giorgio: Para ser honesto, qualquer esforço desse tipo teria que trabalhar na reconstrução do C ++ desde o início, ou seja, criando uma nova linguagem . E isso tem sido feito ... muitas vezes.
Lightness Races em órbita
106

Isso define:

  • uma estrutura anônima,
  • que é derivado publicamente de bar
  • que ( anonymously) define nada além do que derivoubar
  • e, finalmente, uma instância chamada "foo" é criada,
  • com uma lista inicializadora vazia

struct : bar {} foo {};
Frunsi
fonte