Есть ли «безопасный» static_cast альтернатива?

Есть ли «безопасная» альтернатива static_cast в C ++ 11/14 или библиотека, которая реализует эту функциональность?

Под «безопасным» я подразумеваю, что приведение должно разрешать только приведение, которое не теряет точности. Так что актерский состав из int64_t в int32_t будет разрешено только если число вписывается в int32_t и еще сообщается об ошибке.

16

Решение

Там в gsl::narrow

узкий // narrow<T>(x) является static_cast<T>(x) если static_cast<T>(x) == x или это бросает narrowing_error

35

Другие решения

У вас есть сценарий использования полностью изменен.

Предполагаемое использование 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 обычно выдает только предупреждение), поэтому убедитесь, что вы используете правильные флаги, чтобы предупреждения воспринимались как ошибки.

21

Вы можете создать свой собственный с 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где статический здесь относится к «определяется во время компиляции».

0
По вопросам рекламы [email protected]