Есть ли "безопасная" альтернатива static_cast? - PullRequest
0 голосов
/ 17 октября 2018

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

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

Ответы [ 3 ]

0 голосов
/ 17 октября 2018

Вы изменили сценарий использования.

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

0 голосов
/ 17 октября 2018

Вы можете создать свой собственный с 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 голосов
/ 17 октября 2018

Есть gsl::narrow

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...