dev compiler c++ c++11

compiler - c++14



¿Por qué mi compilador no reconoce “Bond()=default;”? (3)

El constructor predeterminado se suprime porque hay miembros constantes que deben inicializarse explícitamente.

Por lo tanto, debido a esa supresión, escribir Bond() = default no reintroduce el constructor predeterminado.

(Puede ver este efecto eliminando todos los constructores de la clase; aún no puede crear una instancia de b ).

Si sueltas la const de los miembros, todo estará bien; aunque otra alternativa es proporcionar un inicializador de corsé o igual para cada miembro const ;

const int payments_per_year = 2; const int period_length_in_months = 6;

por ejemplo.

Por favor mira este codigo

class Bond { public: Bond(int payments_per_year, int period_lengths_in_months); Bond() = default; private: const int payments_per_year; const int period_length_in_months; }; int main() { Bond b; // Error here }

Al intentar compilar me sale un error:

error C2280: ''Bond :: Bond (void)'': intentando hacer referencia a una función eliminada ".

No es una infracción de "regla de 3" ya que he agregado nuevamente el constructor predeterminado.

¿Por qué el compilador no reconoce a Bond() = default; ?


Otra solución es especificar un valor predeterminado en la declaración de las constantes:

const int payments_per_year = {12};

El constructor con valor aún puede omitir esto, pero permite que el constructor predeterminado continúe.

Esta también es una forma muy flexible de simplificar sus casos de múltiples constructores.


Usted está siendo afectado por la sección [class.default.ctor]p2 del borrador del estándar C ++ (o [class.ctor]p5 en C ++ 11) que dice:

Un constructor predeterminado predeterminado para la clase X se define como eliminado si:
...
- cualquier miembro de datos no estáticos no variante de tipo cualificado por const (o conjunto de ellos) sin inicializador con refuerzo o igual no tiene un constructor predeterminado proporcionado por el usuario,
...

La posible clave para solucionar su problema es con la frase sin inicializador de refuerzo o igual por lo que si proporciona inicializador de apoyo o igual que solucionará su problema, por ejemplo:

const int payments_per_year{12}; const int period_length_in_months{48};

brace-or-equal-initializer no requiere llaves, podemos ver esto en la gramática:

brace-or-equal-initializer: = initializer-clause braced-init-list

pero el uso de una inicialización uniforme tiene algunas ventajas, como hacer que las conversiones de estrechamiento no estén bien formadas, por lo que vale la pena acostumbrarse a usarlas.

Tanto gcc como clang proporcionan diagnósticos más significativos para esto, vea la sesión de godbolt en vivo . A veces puede ser útil probar su código en varios compiladores, especialmente si tiene un caso de prueba mínimo como este, por ejemplo, clang dice:

warning: explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted] Bond() = default; ^ note: default constructor of ''Bond'' is implicitly deleted because field ''payments_per_year'' of const-qualified type ''const int'' would not be initialized const int payments_per_year; ^ ...