c++ - after - ¿Escribe id de std:: string para variable vs. string en argumento?
const after a function c++ (3)
Me referí a http://en.cppreference.com/w/cpp/language/typeid para escribir código que hace diferentes cosas para diferentes tipos.
El código es el siguiente y la explicación se da en los comentarios.
#include <iostream>
#include <typeinfo>
using namespace std;
template <typename T>
void test_template(const T &t)
{
if (typeid(t) == typeid(double))
cout <<"double/n";
if (typeid(t) == typeid(string))
cout <<"string/n";
if (typeid(t) == typeid(int))
cout <<"int/n";
}
int main()
{
auto a = -1;
string str = "ok";
test_template(a); // Prints int
test_template("Helloworld"); // Does not print string
test_template(str); // Prints string
test_template(10.00); // Prints double
return 0;
}
¿Por qué test_template(str)
imprime "cadena" mientras que test_template("Helloworld")
no lo hace?
Por cierto, mi versión g ++ es g ++ (Ubuntu 5.4.0-6ubuntu1 ~ 16.04.4) 5.4.0 20160609.
En esta llamada
test_template("Helloworld"); // Does not print string
el argumento "Helloworld"
es un literal de cadena que tiene tipo const char[11]
.
Porque el parámetro de función es un tipo referenciado
void test_template(const T &t)
^^^
luego, dentro de la función, el argumento (más precisamente el parámetro) tiene el tipo const char ( &t )[11]
.
Los literales de cadena en C ++ tienen tipos de matrices de caracteres constantes con el número de elementos igual al número de caracteres en el literal de cadena más el cero final.
En esta llamada
test_template(str);
el argumento tiene el tipo std::string
porque la variable str
está declarada como
string str = "ok";
^^^^^^
Se inicializó con la cadena literal "ok"
sin embargo, el objeto en sí es del tipo std::string
.
Los literales de cadena como "Helloworld"
son matrices de caracteres constantes.
La clase std::string
tiene un constructor que puede llevar los punteros a los literales de cadena, pero un literal de cadena no es en sí mismo un objeto std::string
.
Como nota al margen, el uso de una función como la suya se considera un olor de código y un mal diseño. Utilice funciones sobrecargadas tomando argumentos diferentes en su lugar. Eso también solucionará tu problema con las cuerdas.
Los literales de cadena en C ++ son de tipo const char[N+1]
, donde N
es el número de caracteres en la cadena. std::string
es una clase de biblioteca estándar que posee una cadena y proporciona una serie de operaciones sobre ella. Una std::string
puede construirse a partir de un const char[N]
, pero no son lo mismo.