una - Constructor de cadenas vacías de C++
inicializacion de variables en c (7)
Soy un principiante de C ++, lo siento si la pregunta es demasiado básica.
He intentado recolectar las cuerdas y probarlas todas (para recordarlas).
string strA(); // string(); empty string // incorrect
string strB("Hello"); // string( const char* str)
string strC("Hello",3); // string( const char* str, size_type length)
string strD(2,''c''); // string( size_type lenght, const char &c)
string strE(strB); // string( const string& s)
cout << strA << endl;
cout << strB << endl;
cout << strC << endl;
cout << strD << endl;
cout << strE << endl;
Todos ellos funcionan a excepción de la ley . Imprime "1". ¿Por qué? ¿Cuál es el tipo de strA en este caso? ¿Cómo puedo verificar el tipo de cosas cuando no estoy seguro?
Me he dado cuenta de que la forma correcta es esta (que por cierto parece ser inconsistente con los otros constructores, a veces parens a veces sin parens):
string strA;
ps: pregunta en negrita, las respuestas irrelevantes usuales se rechazarán.
El compilador interpreta la string strA()
como un prototipo de función de una función que toma argumentos nulos y devuelve un objeto de tipo cadena. Si desea crear un objeto de cadena vacío, use la string strA;
(sin paréntesis)
En C ++, como en C, hay una regla que dice que cualquier cosa que parezca una declaración será tratada como una declaración.
string strA();
Parece una declaración de función, por lo que se trata como una. Necesitas:
string strA;
Este es un gotcha muy popular. La gramática de C ++ es ambigua. Una de las reglas para resolver ambigüedades es "si algo parece ser una declaración, es una declaración". En este caso, en lugar de definir una variable, se declaró un prototipo de función.
string strA();
es equivalente a
string strA(void);
un prototipo de una función no arg que devuelve cadena.
Si desea llamar explícitamente al constructor no-arg, intente esto:
string strA=string();
No es totalmente equivalente; significa "crear una cadena temporal utilizando el constructor no-arg y luego copiarla para inicializar la variable strA", pero el compilador puede optimizarla y omitir la copia.
Imprime 1
porque los punteros a las funciones siempre se convierten en numéricos como true
.
No creo que en este caso, se aplique la regla "si podría ser una declaración, se considera una declaración". Como en lo siguiente, ambas cosas son declaraciones.
string a;
string a();
El uno es la declaración de un objeto, y el otro es la declaración de una función. La regla se aplica en otros casos. Por ejemplo, en este caso:
string a(string());
En ese caso, string()
puede significar dos cosas.
- Declaración de un parámetro de función sin nombre
- Expresión creando una
string
construida por defecto.
El fule se aplica aquí, y se considera que string()
significa lo mismo que el siguiente parámetro con nombre (los nombres son irrelevantes en los parámetros al declarar una función)
string a(string im_not_relevant());
Si una función toma como parámetro una matriz u otra función, ese parámetro decae en un puntero. En el caso de un parámetro de función, a un puntero a la función. Por lo tanto, es equivalente a lo siguiente, que puede parecer más familiar
string a(string (*im_not_relevant)());
Pero en tu caso, es más bien la sintaxis que se está interponiendo en el camino. Está diciendo que la siguiente es una declaración de función. Nunca puede ser la declaración de un objeto (¡aunque eso probablemente fue pensado por el programador!)
string a();
Entonces, en primer lugar, no hay ambigüedad en este contexto, y por lo tanto declara una función. Dado que la string
tiene un constructor definido por el usuario, solo puede omitir los paréntesis, y el efecto sigue siendo el mismo que el previsto.
Se considera
string strA();
como una declaracion de funcion.
Para el uso de constructor por defecto:
string strA;
tkopec tiene razón en por qué no funciona. Para responder a su segunda pregunta, aquí tiene cómo marcar el tipo:
template<typename TEST> void Error_() {
TEST* MakeError = 1;
}
Llamando Error_(StrA);
obtendrá un error de compilación, y su compilador probablemente le dirá que sucedió en Error_< std::basic_string<char, std::allocator<char> > (*)(void)>(std::basic_string<char, std::allocator<char> > (*)(void))
Ahora, std :: basic_string> es solo std :: string, así que esto realmente significa Error_< std::string (*)(void)> (std::string (*)(void))
. La parte entre ''<>'' se repite entre ''()'', y ese es el tipo de strA. En este caso, std::string (*)(void)
.