guidelines - c++ best practices
¿Existe una alternativa estática "segura"? (3)
¿Existe una alternativa "segura" a static_cast
en C ++ static_cast
o una biblioteca que implementa esta funcionalidad?
Por "seguro" me refiero a que el yeso solo debe permitir moldes que no pierdan precisión. Por lo tanto, una int64_t
de int64_t
a int32_t
solo se permitiría si el número se ajusta a un int32_t
y, de lo contrario, se informa de un error.
Hay gsl::narrow
estrecho //
narrow<T>(x)
esstatic_cast<T>(x)
sistatic_cast<T>(x) == x
o arrojanarrowing_error
Puedes crear el tuyo propio con sfinae. Aquí hay un ejemplo:
template <typename T, typename U>
typename std::enable_if<sizeof(T) >= sizeof(U),T>::type
safe_static_cast(U&& val)
{
return static_cast<T>(val);
}
int main()
{
int32_t y = 2;
std::cout << safe_static_cast<int32_t>(y) << std::endl;
std::cout << safe_static_cast<int16_t>(y) << std::endl; // compile error
}
Esto se compilará solo si el tamaño al que se convierte es> = el tamaño de la fuente.
Pruébalo here
Puede complicar esto aún más usando numeric_limits para otros tipos y type_traits .
Observe que mi solución es una solución en tiempo de compilación, porque usted preguntó acerca de static_cast
, donde estática aquí se refiere a "determinado en tiempo de compilación".
Tienes el caso de uso invertido.
El uso previsto de static_cast
(y las otras static_cast
estilo c ++) es indicar las intenciones del programador. Cuando escribe auto value = static_cast<int32_t>(value_64);
, está diciendo "Sí, mucho * intento * reducir este valor, posiblemente truncarlo, cuando realice esta tarea" . Como resultado, un compilador, que podría haberse inclinado a quejarse acerca de esta conversión en circunstancias normales (como si hubiera escrito int32_t value = value_64;
) en cambio, observa "bueno, el programador me ha dicho que esto es lo que pretendían ¿Por qué me mentirían? y compilará silenciosamente el código.
Si desea que su código C ++ advierta o emita un error en las conversiones no seguras, debe no usar explícitamente static_cast
, const_cast
, reinterpret_cast
y dejar que el compilador haga su trabajo. Los compiladores tienen indicadores que cambian la forma en que se tratan las advertencias (la conversión de int64_t
a int32_t
general solo produce una Advertencia), así que asegúrese de estar utilizando los indicadores correctos para forzar que las advertencias se traten como errores.