Constructor de copia no es llamado para copiar-inicialización o optimizado?
-
08-10-2019 - |
Pregunta
Si constructor de copia se hace private
después en
Caso 1:. No hay error, el compilador no le importa si el constructor de copia se define en la clase
Caso 2:. Error, constructor de copia privada y es cuando se hace public
, se elide
Qué se optimiza la copia directamente sin ser notar que si el constructor se hizo private
?
#include <string>
using std::string;
class T
{
string s;
T(const T &obj):s(obj.s){}
public:
T(const string &str):s(str){}
};
int main()
{
T a = ("Copy Initialization"); //Case: 1
T b = T("Copy Initialization"); //Case: 2
}
Solución
Case 2 viene bajo 12,8 / 31 en N3225:
Un programa está mal formada, si el copiar / constructor de movimiento o la copia / movimiento operador de asignación para un objeto es implícitamente ODR-utilizado y el especial función miembro no es accesible.
El hecho de que la copia se ctor elided no significa que no se utiliza-ODR. 3,2 / 2:
Un miembro de un conjunto de candidatos funciones se ODR-utilizan si es seleccionado por la resolución de sobrecarga cuando que se refiere a partir de una expresión potencialmente-evaluado. [Nota: Incluye llamadas a la llamada funciones (5.2.2), Ator oper- sobrecarga (Cláusula 13), el usuario-de fi Ned conversiones (12.3.2), la asignación función para la colocación de nuevo (5.3.4), como se así como la inicialización no predeterminada (8.5). Un constructor copiar o mover constructor es ODR-usado incluso si el llamada es en realidad por el elided implementación. -fin nota]
Cuidado por supuesto que MSVC es no totalmente C ++ 0x-compatible, porque (a) C ++ 0x no es un estándar, sin embargo, y no está finalizado; y (b) MSVC no ha implementado todo al día de todos modos. Pero esto no se cambia sustancialmente de C ++ 03, así que estoy bastante seguro de la explicación aún mantiene.
Caso 1 pasaría a estar bajo esto también, excepto que en los dos compiladores de C ++ 03 He comprobado que no llegue tan lejos porque no hay posible conversión de una cadena literal a T. No puedo ser molestado para comprobar si hay algún secuencias de conversión adicionales permitidos en C ++ 0x, podría haber una nueva en cualquier lugar cláusula: -)
Es todavía un misterio para mí por qué MSVC permite que el caso 1 vez, incluso con una copia ctor público. ¿Permite que en estricto C ++ 03 modo?
Otros consejos
Caso 1:. No hay error , el compilador no le importa si el constructor de copia se define en la clase
T a = ("Copy Initialization"); href="http://ideone.com/DbYAx" rel="nofollow"> debería dar una de error porque no hay ningún constructor adecuado convertir de "const char [20]"
a "T"
Te ha T a = std::string("Copy Initialization");
media?
Qué se optimiza la copia directamente sin ser notar que si el constructor se hizo privada?
No, no puede. Los compiladores suelen realizar análisis sintáctico y semántico antes de la fase de optimización de código.