León
Tengo una clase:
class Symbol_t {
public:
Symbol_t( const char* rawName ) {
memcpy( m_V, rawName, 6 * sizeof( char ) );
};
string_view strVw() const {
return string_view( m_V, 6 );
};
private:
char m_V[6];
}; // class Symbol_t
y hay una función lib que no puedo modificar:
extern bool loadData( const string& strSymbol );
Si hay una variable local:
Symbol_t symbol( "123456" );
Cuando necesito llamar a loadData, no me atrevo a hacerlo así:
loadData( string( symbol.strVw().begin(), symbol.strVw().end() ) );
tengo que hacer asi:
string_view svwSym = symbol.strVw();
loadData( string( svw.begin(), svw.end() ) );
Mi pregunta: ¿Es correcto el primer método? o debo usar el segundo?
Porque creo que en el Método 1, los iteradores que pasé al constructor de std::string son de dos objetos String_vew diferentes y, en teoría, el resultado no está definido, aunque obtendríamos el resultado esperado con casi todos los compiladores de C++.
¡Cualquier sugerencia será apreciada! gracias.
StoryTeller – Unslander Mónica
No hay necesidad de usar el c’tor tomando un rango. std::string
tiene un constructor que opera en términos de std::string_view
, numero 10 en la lista. cuyo efecto es
template < class T > explicit basic_string( const T& t, const Allocator& alloc = Allocator() );
Implícitamente convierte t en una vista de cadena sv como si fuera
std::basic_string_view<CharT, Traits> sv = t;
luego inicializa la cadena con el contenido desv
como si porbasic_string(sv.data(), sv.size(), alloc)
. Esta sobrecarga solo participa en la resolución de sobrecarga sistd::is_convertible_v<const T&, std::basic_string_view<CharT, Traits>>
es cierto ystd::is_convertible_v<const T&, const CharT*>
Es falso.
Como ambas condiciones se cumplen para std::string_view
mismo, podemos escribir la llamada a loadData
como simplemente:
loadData( std::string( symbol.strVw() ) );
Si tiene alguna vista de cadena en C++ que desea convertir a formato de cadena (para que pueda volver a una función después de realizar todos sus análisis, por ejemplo), puede realizar ese cambio haciendo esto:
string_view sv;
string s = {sv.begin(), sv.end()};
Yendo al revés, para obtener una vista de cadena de una cadena (para obtener un puntero a esa cadena), puede hacer esto:
string s;
string_view sv = string_view(s);
Tenga en cuenta que la subcadena y una variedad de otras operaciones se pueden realizar en string_view al igual que en la cadena.
-
Sin embargo, ¿esto no hace una copia completa de la cadena? El propósito principal de
string_view
es evitar hacer exactamente eso.– Roflcopter4
22 de noviembre de 2022 a las 11:13
Maxim Egorushkin
¿Es correcto el primer método?
es, desde strVw
devuelve idéntico string_view
s: todos apuntan a lo mismo m_V
y tienen el mismo tamaño.
La corrección aquí depende de cómo strVw
está implementado.
o debo usar el segundo?
Yo crearía una función de conversión:
inline std::string as_string(std::string_view v) {
return {v.data(), v.size()};
}
Y usa eso:
loadData(as_string(symbol.strVw()));
Este método es seguro independientemente de strVw
implementación.