c++ - tipos - si un programa compila y ejecuta pero da una salida incorrecta esto se conoce como un error de
Vector de const objetos que dan error de compilaciĆ³n. (2)
El uso del método push_back
es el problema. emplace_back
compilará. Otra alternativa (dependiendo de la situación en general que no describas aquí) sería usar un vector<A const&>
si los elementos insertados tienen una vida fuera del vector. Los elementos en un vector no necesitan ser asignables, pero cuando no lo son, algunas funciones y algoritmos de los miembros no se pueden usar.
Explicación:
push_back
se supone que primero construye por defecto una A en el vector, luego asigna (usando copia-construcción) la referencia dada. Esto rompe tu calificación de const
, por lo tanto no compila.
emplace_back
usa el "reenvío perfecto" para invocar al constructor real directamente en su lugar.
He declarado lo siguiente en mi código.
vector <const A> mylist;
Me sale el siguiente error de compilación -
new_allocator.h:75: error: `const _Tp* __gnu_cxx::new_allocator<_Tp>::address(const _Tp&) const /[with _Tp = const A]'' and `_Tp* __gnu_cxx::new_allocator<_Tp>::address(_Tp&) const [with _Tp = const A]'' cannot be overloaded
Pero si declaran ...
vector <A> mylist;
mi código compila
¿No está permitido const en este contexto?
Estoy copiando mi código aquí para la referencia de todos -
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A () {cout << "default constructor/n";}
A (int i): m(i) {cout << "non-default constructor/n";}
private:
int m;
};
int main (void)
{
vector<const A> mylist;
mylist.push_back(1);
return 0;
}
Los elementos en un vector deben ser asignables (o, en versiones más recientes del estándar, móviles). const
objetos const
no son asignables, por lo que intentar almacenarlos en un vector fallará (o al menos puede fallar, el código no es válido, pero un compilador puede aceptarlo de todos modos, si así lo decide, aunque la mayoría de los programadores generalmente Prefiero que el código inválido sea rechazado).
Supongo que para los verdaderamente pedantes, si quisieras lo suficiente, podrías definir un tipo que fuera asignable a pesar de ser const
, algo como esto:
class ugly {
mutable int x;
public:
ugly const &operator=(ugly const &u) const {
x = u.x;
return *this;
}
};
Creo que deberías poder almacenar artículos de este tipo en un vector
aunque sean const
. Una prueba rápida de crear un vector de estos tiene éxito con VC ++. Esto falló con algunos compiladores más antiguos (p. Ej., Falló con g ++ 4.8.1), pero funciona con los razonablemente recientes (VC ++ al menos 2015, g ++ al menos 5.4 y clang ++ al menos 4.0, aunque no tengo '' Intenté rastrear la primera versión de cada uno que lo apoyaba).
Para un compilador actual, un tipo que admita mover objetos const
podría funcionar igual de bien. Pero, por si acaso no era obvio: esto le permite modificar un objeto aunque esté marcado como const
. Eso es claramente una violación directa de las expectativas de cualquier usuario razonable, por lo que es principalmente un problema, no una solución.