Constructor predeterminado eliminado. Todavía se pueden crear objetos ... a veces

La visión ingenua, optimista y oh ... tan equivocada de la sintaxis de inicialización uniforme de c ++ 11

Pensé que desde C ++ 11 los objetos de tipo definidos por el usuario deberían construirse con el nuevo{...} sintaxis en lugar de la antigua(...) sintaxis (excepto para el constructor sobrecargado parastd::initializer_list y parámetros similares (p. ej.std::vector: tamaño ctor vs 1 elem init_list ctor)).

Los beneficios son: no hay conversiones implícitas estrechas, no hay problema con el análisis más irritante, consistencia (?). No vi ningún problema ya que pensé que eran lo mismo (excepto el ejemplo dado).

Pero no lo son.

Una historia de pura locura.

los{} llama al constructor predeterminado.

... Excepto cuando:

el constructor predeterminado se elimina yNo hay otros constructores definidos.

¿Entonces parece que el valor inicializa el objeto? ... Incluso si el objeto ha eliminado el constructor predeterminado, el{} puede crear un objeto ¿Esto no supera todo el propósito de un constructor eliminado?

...Excepto cuando:

el objeto tiene un constructor predeterminado eliminado yOtros constructores definidos.

Entonces falla concall to deleted constructor.

...Excepto cuando:

el objeto tiene un constructor eliminado yningún otro constructor definido yal menos un miembro de datos no estático.

Entonces falla con falta de inicializadores de campo.

Pero entonces puedes usar{value} para construir el objeto.

Ok, tal vez esto sea lo mismo que la primera excepción (valor init el objeto)

...Excepto cuando:

la clase tiene un constructor eliminadoy al menos un miembro de datos predeterminado en clase inicializado.

Entonces ni{} ni{value} puede crear un objeto

Estoy seguro de que me perdí algunos. La ironía es que se llamauniforme sintaxis de inicialización Digo de nuevo:UNIFORME sintaxis de inicialización

¿Qué es esta locura?

Escenario AConstructor predeterminado eliminado:
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.
Escenario BConstructor predeterminado eliminado, otros constructores eliminados
struct foo {
  foo() = delete;
  foo(int) = delete;
};

foo f{}; // OK
Escenario CConstructor predeterminado eliminado, otros constructores definidos
struct foo {
  foo() = delete;
  foo(int) {};
};

foo f{}; // error call to deleted constructor
Escenario DConstructor predeterminado eliminado, ningún otro constructor definido, miembro de datos
struct foo {
  int a;
  foo() = delete;
};

foo f{}; // error use of deleted function foo::foo()
foo f{3}; // OK
Escenario EConstructor predeterminado eliminado, constructor T eliminado, miembro de datos T
struct foo {
  int a;
  foo() = delete;
  foo(int) = delete;
};

foo f{}; // ERROR: missing initializer
foo f{3}; // OK
Escenario FConstructor predeterminado eliminado, inicializadores de miembros de datos en clase
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)`

Respuestas a la pregunta(3)

Su respuesta a la pregunta