Cómo provocar un error en tiempo de compilación si se llama a una sobrecarga específica de una función?
Según https://en.cppreference.com/w/cpp/string/basicstringview/basicstringview, la clase std::basic_string_view
tiene 7 constructores sobrecargados. Solo me interesan 2 de ellos, ya que actualmente no utilizo el resto en mi código.
Estos son los constructores que me interesan:
constexpr basic_string_view( const CharT* s, size_type count );
constexpr basic_string_view( const CharT* s );
Necesito evitar que el código llame al segundo (debido a que podría causar un desbordamiento de búfer para búferes no terminados en nulo).
Tengo algo como esto:
#include <iostream>
#include <sstream>
#include <string>
#include <array>
void func( const std::string_view str )
{
if ( str.empty( ) )
{
return;
}
std::stringstream ss;
if ( str.back( ) == '\0' )
{
ss << str.data( );
}
else
{
ss << std::string{ str };
}
}
int main()
{
std::array<char, 20=""> buffer { };
std::cin.getline( buffer.data( ), 20 );
const std::string_view sv { buffer.data( ), buffer.size( ) };
func( sv ); // debería estar permitido
func( { buffer.data( ), buffer.size( ) } ); // debería estar permitido
func( buffer.data( ) ); // ¡NO debería estar permitido!
}
¿Cuál es la forma correcta de hacer esto?</char,>
davy.ai
El segundo constructor (
basic_string_view(const CharT* s)
) debe ser evitado porque asume que la cadena de entrada está terminada en nulo, lo cual puede causar desbordamiento de búfer para cadenas no terminadas en nulo. Para evitar que el código llame al segundo constructor, una posible solución es crear una función auxiliar que tome una cadena no terminada en nulo y la convierta en una cadena terminada en nulo antes de construirstd::string_view
. Aquí está el código modificado:La función
make_string_view
toma un puntero a una cadena (s
) y un tamaño (count
) y construye internamente una cadena terminada en nulo antes de crear unstd::string_view
usando el primer constructor. De esta manera, podemos asegurar quebasic_string_view
siempre se inicializa con una cadena terminada en nulo y que el constructor de cadena no terminada en nulo nunca se utiliza.</char,>