私の知る限り、_std::to_integer<T>
_はT(value)
と同等です。ここで、value
は_std::byte
_型の変数です。
主要なコンパイラからいくつかの実装を調べたところ、この場合equivalentは文字通りとして実装を意味することがわかりました。つまり、ほとんどの場合、_to_integer
_は実際には次のように実装されます。
_return T(value);
_
そして、それだけです。
私が理解していないのは、そのような関数の目的は何ですか?
皮肉なことに、短所は長所を超えています。とにかく直接インライン化される可能性が高いCのようなキャストを回避するために、このような関数のヘッダー全体を含める必要があります。
他の理由はありますか、それとも実際にはCのようなキャストの代わりにNice lookingの選択肢にすぎませんか?
それは本当にCのようなキャストのための本当に見栄えの良い代替品であり、それ以上は何ですか?
あなたはそれがいくつかの些細な詳細であるかのように言っています。
キャストは危険です。何かを間違った型にキャストするのは簡単で、多くの場合、コンパイラーはそれを正確に行うことを妨げません。さらに、C++では_std::byte
_は整数型ではないため、数値のバイト値を処理するには多くのキャストが必要になります。明示的に整数に変換する関数を使用すると、より安全なユーザーエクスペリエンスが実現します。
たとえば、float(some_byte)
は完全に合法ですが、to_integer<float>(some_byte)
は明示的に禁止されています。 _to_integer<T>
_では、T
が整数型である必要があります。
_to_integer
_はsaferの代替です。
そのような関数のヘッダー全体を含める必要があります
「ヘッダー全体」とは、同じヘッダーが_std::byte
_を取得したことを意味し、したがって定義によりすでに含まれています...
std::to_integer<T>(some_byte)
は、実際にコンパイルされる場合、T(some_byte)
と同等です。 T(some_byte)
は(T)some_byte
の安全でないCスタイルのキャストと同等であり、 怖いこと を実行できます。一方、std::to_integer
は、安全な場合にのみ機能するように適切に制限されています。
このオーバーロードは、
std::is_integral_v<IntegerType>
がtrueの場合にのみ、オーバーロードの解決に参加します。
T
が実際には整数型ではなく、未定義の動作が発生する可能性がある場合、コードはコンパイルされません。 some_byte
が実際にはstd::byte
ではなかった場合、未定義の動作が発生する可能性があるのではなく、コードはコンパイルされません。
すでに述べた意図と安全性の問題の表現を超えて、私はそれがstd::to_string
と将来的にはより多くのオーバーロードを持つ可能性があります。
Cスタイルのキャストはstd::to_integer<T>
と同等ではありません。以下の例を参照してください。
std::to_integer<T>
は、std::is_integral_v<T>
がtrueの場合にのみ過負荷解決に参加します。
#include <cstddef>
#include <iostream>
template <typename T>
auto only_return_int_type_foo(std::byte& b)
{
return std::to_integer<T>(b);
}
template <typename T>
auto only_return_int_type_bar(std::byte& b)
{
return T(b);
}
int main()
{
std::byte test{64};
// compiles
std::cout << only_return_int_type_foo<int>(test) << std::endl;
// compiler error
std::cout << only_return_int_type_foo<float>(test) << std::endl;
// compiles
std::cout << only_return_int_type_bar<int>(test) << std::endl;
// compiles
std::cout << only_return_int_type_bar<float>(test) << std::endl;
}