C++ 11/14のstatic_cast
の「安全な」代替手段、またはこの機能を実装するライブラリはありますか?
「安全」とは、キャストが精度を失わないキャストのみを許可することを意味します。したがって、int64_t
からint32_t
へのキャストは、番号がint32_t
に収まる場合にのみ許可され、そうでない場合はエラーが報告されます。
_gsl::narrow
_ があります
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++コードが安全でない変換で警告またはエラーをスローするようにするには、明示的にnotstatic_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
について尋ねたからです。