c++ - separadores - ¿cuál es el valor del siguiente literal? 018
¿Por qué los literales de cadena definidos por el usuario y los literales enteros tienen un comportamiento diferente? (1)
Estoy aprendiendo sobre literales definidos por el usuario, y confundido con el siguiente código de prueba:
std::chrono::seconds operator"" _s(unsigned long long s) {
return std::chrono::seconds(s);
}
std::string operator"" _str(const char *s, std::size_t len) {
return std::string(s, len);
}
int main() {
auto str = "xxxxx"_str;
std::cout << str.size() << std::endl; // works
auto sec = 4_s;
std::cout << sec.count() << std::endl; // works
std::cout << "xxxxx"_str.size() << std::endl; // works
std::cout << 4_s.count() << std::endl; // does **NOT** work!
return 0;
}
El compilador da el siguiente mensaje de error:
error: no hay un operador literal coincidente para la llamada a ''operator "" _ s.count'' con un argumento de tipo ''unsigned long long'' o ''const char *'', y no hay una plantilla de operador literal coincidente
cout << 4_s.count () << endl;
Parece que toma _s.count como un literal definido por el usuario. Además, un literal de coma flotante se comporta como un literal entero.
¿Por qué los literales enteros definidos por el usuario y los literales de cadena tienen un comportamiento diferente?
¡Así es como funcionan los literales de punto flotante !
Agrega un par de paréntesis y debería funcionar:
std::cout << (4_s).count();
O alternativamente, sepárelos (para evitar que el compilador lo interprete como un literal de coma flotante constante fraccional mal formado):
std::cout << 4_s .count();
// ^ Space here!
Referencia: CppReference.com
En la sección de Notas de la referencia anterior,
Debido a la munch máxima, los enteros definidos por el usuario y los literales de punto flotante que terminan en [
p
,P
, (desde C ++ 17)]e
yE
, cuando son seguidos por los operadores+
o-
, deben separarse del operador con espacios en blanco en la fuente:
long double operator""_E(long double); long double operator""_a(long double); int operator""_p(unsigned long long); auto x = 1.0_E+2.0; // error auto y = 1.0_a+2.0; // OK auto z = 1.0_E +2.0; // OK auto w = 1_p+2; // error auto u = 1_p +2; // OK
Por lo tanto, cuando se trata de puntos, que se usan como punto decimal , se deben separar de cualquier parte posterior, o se tratarán como parte del número de punto flotante .
He probado el ejemplo anterior de CppReference y recibí un mensaje de error muy silimar:
test.cpp:19:10: error: unable to find numeric literal
operator ''operator""_E+2.0''
^^^^^^
auto x = 1.0_E+2.0; // error
¿ _E+2.0
cómo _E+2.0
se considera un sufijo ud completo?
Mi intento de explicación original se puede encontrar en el historial de revisiones de esta publicación.