invalid from fpermissive error conversion c++ string vector

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:

  1. vector::emplace
  2. vector::emplace_back
  3. vector::~vector

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:

  1. Realice la optimización de cadenas cortas , evitando potencialmente la asignación de almacenamiento dinámico, con little o ninguna sobrecarga de almacenamiento
  2. Utilice char_traits , uno de los argumentos de la plantilla de la string , para definir cómo deben implementarse las operaciones en los primitivos contenidos (de los cuales solo se implementan char , wchar_t , char16_t y char32_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:

  1. Solo se char32_t los tipos primitivos char , wchar_t , char16_t o char32_t . Obviamente, las primitivas de tamaños de hasta 32 bits, podrían usar su tipo de char_type tamaño equivalente: https://stackoverflow.com/a/35555016/2642059 , pero para las primitivas como la long long se debería escribir una nueva especialización de char_traits , y la idea de especializar char_traits::eof y char_traits::not_eof lugar de solo usar vector<long long> no parece ser el mejor uso del tiempo.
  2. Debido a la optimización de cadenas cortas, los iteradores son invalidados por todas las operaciones que invalidarían un iterador vector , pero string iteradores de string son invalidados adicionalmente por string::swap y string::operator=

Diferencias adicionales en las interfaces de vector y string :

  1. No hay una string::data mutable string::data : ¿Por qué std :: string.data () no proporciona un carácter mutable *?
  2. string proporciona funcionalidad para trabajar con palabras no disponibles en vector : 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
  3. Finalmente, en todas partes el vector acepta argumentos de otro vector , la string acepta una string o un char*

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

En la práctica esta diferencia no es tan importante.


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:

  1. 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*)]; }; };

  2. 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 miembros std::basic_string::c_str() y std::basic_string::data() demasiado caros de implementar).
    Sin embargo, C ++ 11 ahora prohíbe este comportamiento.

  3. 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 para std::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 no std::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).