visual studio microsoft español descargar community c++ c++11 initialization language-lawyer aggregate-initialization

c++ - studio - La inicialización agregada no mantiene el acceso del constructor



visual studio installer (1)

Esta pregunta ya tiene una respuesta aquí:

Dado el ejemplo que se muestra a continuación, me sorprendió descubrir que, a pesar de que el constructor predeterminado se eliminó explícitamente (o se estableció de forma predeterminada para ese asunto), la inicialización agregada siguió siendo posible.

#include <iostream> struct DefaultPrivate { const int n_; static const DefaultPrivate& create(); private: DefaultPrivate() = delete; }; const DefaultPrivate& DefaultPrivate::create() { static DefaultPrivate result{10}; return result; } int main() { DefaultPrivate x; //Fails DefaultPrivate y{10};//Works return 0; }

¿La relación entre la construcción privada predeterminada (o eliminada) y la inicialización agregada no están especificadas en el estándar?

Este fue el caso tanto en GCC 6.3 como en VCC 2017

La razón por la que hago la pregunta es porque esperaba que el cambio de acceso al constructor predeterminado impidiera la inicialización de agregado público


Desde C ++ 11, para la inicialización de la lista ,

Si T es un tipo agregado, se realiza la inicialización agregada.

Y con C ++ 11 un agregado es uno de los siguientes tipos:

...

tipo de clase (típicamente, struct o union), que tiene

  • ...

  • no (explicitly defaulted or deleted constructors are allowed) (since C++11) proporcionados por el usuario , inherited, or explicit (since C++17) (explicitly defaulted or deleted constructors are allowed) (since C++11) constructores (explicitly defaulted or deleted constructors are allowed) (since C++11)

  • ...

Esto significa que desde C ++ 11, la clase con constructores explícitamente eliminados todavía se considera como un tipo agregado, luego se permite la inicialización agregada.

Y el efecto es:

Cada direct public base, (since C++17) elemento de matriz, o miembro de clase no estático, en orden de subíndice / apariencia de matriz en la definición de clase, se inicializa desde la cláusula correspondiente de la lista de inicializadores.

Tenga en cuenta que para DefaultPrivate y{10}; En el proceso anterior, el constructor predeterminado no se considerará en absoluto, entonces el hecho de que se declare como delete y private no tendrá importancia.

Por cierto: para DefaultPrivate x; se realiza la inicialización predeterminada ,

si T es un tipo de clase que non-POD (until C++11) , los constructores se consideran y se someten a una resolución de sobrecarga frente a la lista de argumentos vacía. Se llama al constructor seleccionado (que es uno de los constructores por defecto) para proporcionar el valor inicial para el nuevo objeto;

por lo que se intenta usar el constructor predeterminado, pero se delete y la compilación falla.

Si usa la inicialización agregada, como DefaultPrivate x{}; , el código también funcionaría bien; y n_ se inicializará el valor (y luego se inicializará en cero ) como 0 .

VIVIR