Construtor padrão excluído. Objetos ainda podem ser criados ... às vezes

A visão ingênua, otimista e oh .. tão errada da sintaxe de inicialização uniforme do c ++ 11

Eu pensei que, desde que os objetos do tipo C ++ 11 definidos pelo usuário devessem ser construídos com o novo{...} sintaxe em vez da antiga(...) sintaxe (exceto para o construtor sobrecarregado porstd::initializer_list e parâmetros semelhantes (por exemplo,std::vector: tamanho ctor vs 1 elem init_list ctor)).

Os benefícios são: sem conversões implícitas estreitas, sem problemas com a análise mais irritante, consistência (?). Não vi nenhum problema, pois pensei que eram os mesmos (exceto o exemplo dado).

Mas eles não são.

Um conto de pura loucura

o{} chama o construtor padrão.

... Exceto quando:

o construtor padrão é excluído enão há outros construtores definidos.

Então, parece que o valor inicializa o objeto? ... Mesmo se o objeto tiver excluído o construtor padrão, o{} pode criar um objeto. Isso não supera todo o objetivo de um construtor excluído?

...Exceto quando:

o objeto possui um construtor padrão excluído eoutro construtor (es) definido (s).

Então falha comcall to deleted constructor.

...Exceto quando:

o objeto tem um construtor excluído enenhum outro construtor definido epelo menos um membro de dados não estático.

Em seguida, falha com os inicializadores de campo ausentes.

Mas então você pode usar{value} para construir o objeto.

Ok, talvez seja o mesmo que a primeira exceção (valor init do objeto)

...Exceto quando:

a classe tem um construtor excluídoe pelo menos um membro da classe padrão inicializado.

Então nem{} nem{value} pode criar um objeto.

Tenho certeza de que perdi alguns. A ironia é que é chamadouniforme sintaxe de inicialização. Eu digo de novo:UNIFORME sintaxe de inicialização.

Que loucura é essa?

Cenário AConstrutor padrão excluído:
struct foo {
  foo() = delete;
};

// All bellow OK (no errors, no warnings)
foo f = foo{};
foo f = {};
foo f{}; // will use only this from now on.
Cenário BConstrutor padrão excluído, outros construtores excluídos
struct foo {
  foo() = delete;
  foo(int) = delete;
};

foo f{}; // OK
Cenário CConstrutor padrão excluído, outros construtores definidos
struct foo {
  foo() = delete;
  foo(int) {};
};

foo f{}; // error call to deleted constructor
Cenário DConstrutor padrão excluído, nenhum outro construtor definido, membro de dados
struct foo {
  int a;
  foo() = delete;
};

foo f{}; // error use of deleted function foo::foo()
foo f{3}; // OK
Cenário EConstrutor padrão excluído, construtor T excluído, membro de dados T
struct foo {
  int a;
  foo() = delete;
  foo(int) = delete;
};

foo f{}; // ERROR: missing initializer
foo f{3}; // OK
Cenário FConstrutor padrão excluído, inicializadores de membros de dados na classe
struct foo {
  int a = 3;
  foo() = delete;
};

/* Fa */ foo f{}; // ERROR: use of deleted function `foo::foo()`
/* Fb */ foo f{3}; // ERROR: no matching function to call `foo::foo(init list)`

questionAnswers(3)

yourAnswerToTheQuestion