¿Por qué std::string no tiene un constructor que tome directamente std::string_view?
Para permitir la construcción de std::string
a partir de std::string_view
, existe un constructor de plantilla:
cpp
template<class T>
explicit basic_string(const T& t, const Allocator& alloc = Allocator());
que solo se habilita si const T&
es convertible a std::basic_string_view<CharT, Traits>
(enlace).
Mientras tanto, hay una guía de deducción especial para deducir basic_string
a partir de basic_string_view
(enlace). Un comentario sobre la guía dice:
Se necesitan guías (2-3) porque los constructores de std::basicstring_views de std::basic_string se hacen con plantillas para evitar causar ambigüedades en el código existente, y esas plantillas no admiten la deducción de argumentos de plantilla de clase.
Entonces, me pregunto, ¿cuál es esa ambigüedad que requiere tener esa guía de deducción y constructor de plantilla en lugar de simplemente tener un constructor que tome std::basic_string_view
, algo así como
cpp
explicit basic_string(basic_string_view<CharT, Traits> sv, const Allocator& alloc = Allocator());
Tenga en cuenta que no estoy preguntando por qué el constructor se marca explícito.
davy.ai
La ambigüedad que requiere la guía de deducción y el constructor de plantillas en lugar de un constructor que tome directamente
std::basic_string_view
es que agregar tal constructor causaría ambigüedad en la código existente. Específicamente, consideremos un escenario donde una función toma un parámetroconst std::basic_string&
y le pasamos unstd::basic_string_view
. Si hubiera un constructor que tomastd::basic_string_view
directamente, sería un candidato viable para construir el argumentostd::basic_string
, lo que potencialmente causaría ambigüedad con los constructores existentes que tomanconst CharT*
,size_type
yAllocator
. Al hacer que el constructor destd::basic_string_view
sea un constructor de plantilla, solo se habilita si el argumento es explícitamente convertible astd::basic_string_view
, evitando tales ambigüedades.