c++ - from - Vector vs cadena
[error] invalid conversion from ''int*'' to ''int''[-fpermissive] (7)
TLDR: la string
s está optimizada para contener solo primitivos de caracteres, el vector
s puede contener primitivos u objetos
La diferencia preeminente entre vector
y string
es que el vector
puede contener correctamente objetos, la string
funciona solo en primitivos. Entonces, vector
proporciona estos métodos que serían inútiles para una string
trabaja con primitivos:
Incluso extender la string
no le permitirá manejar correctamente los objetos, ya que carece de un destructor. Esto no debe verse como un inconveniente, ya que permite una optimización significativa sobre el vector
en esa string
puede:
- Realice la optimización de cadenas cortas , evitando potencialmente la asignación de almacenamiento dinámico, con little o ninguna sobrecarga de almacenamiento
- Utilice
char_traits
, uno de los argumentos de la plantilla de lastring
, para definir cómo deben implementarse las operaciones en los primitivos contenidos (de los cuales solo se implementanchar
,wchar_t
,char16_t
ychar32_t
: http://en.cppreference.com/w/cpp/string/char_traits )
Particularmente relevantes son char_traits::copy
, char_traits::move
, y char_traits::assign
lo que obviamente implica que se char_traits::assign
la asignación directa, en lugar de la construcción o la destrucción, lo cual, de nuevo, es preferible para las primitivas. Toda esta especialización tiene los inconvenientes adicionales de string
que:
- Solo se
char32_t
los tipos primitivoschar
,wchar_t
,char16_t
ochar32_t
. Obviamente, las primitivas de tamaños de hasta 32 bits, podrían usar su tipo dechar_type
tamaño equivalente: https://stackoverflow.com/a/35555016/2642059 , pero para las primitivas como lalong long
se debería escribir una nueva especialización dechar_traits
, y la idea de especializarchar_traits::eof
ychar_traits::not_eof
lugar de solo usarvector<long long>
no parece ser el mejor uso del tiempo. - Debido a la optimización de cadenas cortas, los iteradores son invalidados por todas las operaciones que invalidarían un iterador
vector
, perostring
iteradores destring
son invalidados adicionalmente porstring::swap
ystring::operator=
Diferencias adicionales en las interfaces de vector
y string
:
- No hay una
string::data
mutablestring::data
: ¿Por qué std :: string.data () no proporciona un carácter mutable *? -
string
proporciona funcionalidad para trabajar con palabras no disponibles envector
:string::c_str
,string::length
,string::append
,string::operator+=
,string::compare
,string::replace
,string::substr
,string::copy
,string::find
,string::rfind
,string::find_first_of
,string::find_first_not_of
,string::flind_last_of
,string::find_last_not_of
,string::operator+
,string::operator>>
, string::operator>> ,string::stoi
, string::stoi , string::stoi ,string::stoul
, string::stoul ,string::stof
, string::stof , string::stof ,stirng::to_string
,string::to_wstring
- Finalmente, en todas partes el
vector
acepta argumentos de otrovector
, lastring
acepta unastring
o unchar*
Tenga en cuenta que esta respuesta se escribe contra C ++ 11, por lo que las string
s deben asignarse de forma contigua.
¿Cuál es la diferencia fundamental, si existe, entre C ++ std :: vector y std :: basic_string?
El basic_string proporciona muchas opciones de comparación específicas de cadena. Tiene razón en que la interfaz de administración de memoria subyacente es muy similar, pero la cadena contiene muchos miembros adicionales, como c_str (), que no tendría sentido para un vector.
La diferencia clave es que std::vector
debe mantener sus datos en la memoria continua, cuando std::basic_string
no puede hacerlo. Como resultado:
std::vector<char> v( ''a'', 3 );
char* x = &v[0]; // valid
std::basic_string<char> s( "aaa" );
char* x2 = &s[0]; // doesn''t point to continuous buffer
//For example, the behavior of
std::cout << *(x2+1);
//is undefined.
const char* x3 = s.c_str(); // valid
Un vector es una estructura de datos que simula una matriz. En el fondo, en realidad hay una matriz (dinámica).
La clase basic_string representa una secuencia de caracteres. Contiene todas las operaciones habituales de una secuencia y, además, contiene operaciones de cadena estándar, como la búsqueda y la concatenación.
Puede usar vector para mantener el tipo de datos que desee std::vector<int> or <float> or even std::vector< std::vector<T> >
pero una basic_string
solo se puede usar para representar "texto".
Una diferencia entre std::string
y std::vector
es que los programas pueden construir una cadena a partir de una cadena terminada en nulo, mientras que con los vectores no pueden.
std::string a = "hello"; // okay
std::vector<char> b = "goodbye"; // compiler error
Esto a menudo hace que sea más fácil trabajar con cuerdas.
basic_string
proporciona basic_string
compilador y bibliotecas estándar, algunas libertades sobre el vector:
La "optimización de cadena pequeña" es válida en cadenas, lo que permite que las implementaciones almacenen la cadena real, en lugar de un puntero a la cadena, en el objeto de cadena cuando la cadena es corta. Algo a lo largo de las líneas de:
class string { size_t length; union { char * usedWhenStringIsLong; char usedWhenStringIsShort[sizeof(char*)]; }; };
En C ++ 03, la matriz subyacente no necesita ser contigua. La implementación de la
basic_string
en términos de algo como una "cuerda" sería posible bajo la norma actual. (Aunque nadie hace esto porque eso haría que los miembrosstd::basic_string::c_str()
ystd::basic_string::data()
demasiado caros de implementar).
Sin embargo, C ++ 11 ahora prohíbe este comportamiento.En C ++ 03,
basic_string
permite que el proveedor del compilador / biblioteca utilice la copia en escritura para los datos (que se pueden guardar en copias), que no está permitido parastd::vector
. En la práctica, esto solía ser mucho más común, pero es menos común hoy en día debido al impacto que tiene sobre el multihilo. Sin embargo, de cualquier manera, su código no puede depender de si o nostd::basic_string
se implementa usando COW.
C ++ 11 de nuevo ahora prohíbe este comportamiento.
También hay algunos métodos de ayuda relacionados con basic_string
, pero la mayoría son simples y, por supuesto, podrían implementarse fácilmente encima de vector
.
basic_string no llama constructores y destructores de sus elementos. vector hace.
el intercambio de cadena básica invalida los iteradores (habilitando la optimización de cadenas pequeñas), el intercambio de vectores no lo hace.
La memoria de cadena básica no se puede asignar continuamente en C ++ 03. El vector es siempre continuo. Esta diferencia se elimina en C ++ 0x [string.require]:
Los objetos de tipo char en un objeto basic_string se almacenarán de forma contigua
basic_string tiene una interfaz para operaciones de cadena. el vector no lo hace.
basic_string puede usar la estrategia de copiar en escritura (en pre C ++ 11). el vector no puede
Citas relevantes para los no creyentes:
[basic.string]:
La plantilla de clase basic_string cumple con los requisitos para un Contenedor de Secuencia (23.2.3), para un Contenedor Reversible (23.2), y para un contenedor compatible con Asignadores (Tabla 99), excepto que basic_string no construye ni destruye sus elementos utilizando allocator_traits :: construct y allocator_- traits :: destroy y que swap () para basic_string invalida los iteradores. Los iteradores admitidos por basic_string son iteradores de acceso aleatorio (24.2.7).