Есть ли «безопасная» альтернатива static_cast
в C ++ 11/14 или библиотека, которая реализует эту функциональность?
Под «безопасным» я подразумеваю, что приведение должно разрешать только приведение, которое не теряет точности. Так что актерский состав из int64_t
в int32_t
будет разрешено только если число вписывается в int32_t
и еще сообщается об ошибке.
Там в gsl::narrow
узкий //
narrow<T>(x)
являетсяstatic_cast<T>(x)
еслиstatic_cast<T>(x) == x
или это бросаетnarrowing_error
У вас есть сценарий использования полностью изменен.
Предполагаемое использование static_cast
(и другие приведения в стиле c ++) указывают на намерения программиста. Когда ты пишешь auto value = static_cast<int32_t>(value_64);
ты говоришь «Да, я очень * намерен * уменьшить это значение, возможно, обрезая его, когда выполняю это назначение». В результате компилятор, который мог бы быть склонен жаловаться на это преобразование при нормальных обстоятельствах (например, если бы вы написали int32_t value = value_64;
вместо этого наблюдает «Хорошо, программист сказал мне, что это то, что они намеревались; почему они лгут мне?» и тихо скомпилирует код.
Если вы хотите, чтобы ваш код C ++ предупреждал или выдавал ошибку при небезопасных преобразованиях, вам необходимо явно не использование static_cast
, const_cast
, reinterpret_cast
и пусть компилятор сделает свою работу. У компиляторов есть флаги, которые меняют способ обработки предупреждений int64_t
в int32_t
обычно выдает только предупреждение), поэтому убедитесь, что вы используете правильные флаги, чтобы предупреждения воспринимались как ошибки.
Вы можете создать свой собственный с sfinae. Вот пример:
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
}
Это скомпилируется, только если размер, который вы приведете, равен> = размеру источника.
Попытайся Вот
Вы можете усложнить это, используя numeric_limits для других типов и type_traits.
Обратите внимание, что мое решение является решением во время компиляции, потому что вы спросили о static_cast
где статический здесь относится к «определяется во время компиляции».