web-dev-qa-db-ja.com

std :: to_integerの目的は何ですか?

私の知る限り、_std::to_integer<T>_はT(value)と同等です。ここで、valueは_std::byte_型の変数です。
主要なコンパイラからいくつかの実装を調べたところ、この場合equivalentは文字通りとして実装を意味することがわかりました。つまり、ほとんどの場合、_to_integer_は実際には次のように実装されます。

_return T(value);
_

そして、それだけです。

私が理解していないのは、そのような関数の目的は何ですか?
皮肉なことに、短所は長所を超えています。とにかく直接インライン化される可能性が高いCのようなキャストを回避するために、このような関数のヘッダー全体を含める必要があります。

他の理由はありますか、それとも実際にはCのようなキャストの代わりにNice lookingの選択肢にすぎませんか?

9
skypjack

それは本当にCのようなキャストのための本当に見栄えの良い代替品であり、それ以上は何ですか?

あなたはそれがいくつかの些細な詳細であるかのように言っています。

キャストは危険です。何かを間違った型にキャストするのは簡単で、多くの場合、コンパイラーはそれを正確に行うことを妨げません。さらに、C++では_std::byte_は整数型ではないため、数値のバイト値を処理するには多くのキャストが必要になります。明示的に整数に変換する関数を使用すると、より安全なユーザーエクスペリエンスが実現します。

たとえば、float(some_byte)は完全に合法ですが、to_integer<float>(some_byte)は明示的に禁止されています。 _to_integer<T>_では、Tが整数型である必要があります。

_to_integer_はsaferの代替です。

そのような関数のヘッダー全体を含める必要があります

「ヘッダー全体」とは、同じヘッダーが_std::byte_を取得したことを意味し、したがって定義によりすでに含まれています...

12
Nicol Bolas

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ではなかった場合、未定義の動作が発生する可能性があるのではなく、コードはコンパイルされません。

9
Justin

すでに述べた意図と安全性の問題の表現を超えて、私はそれがstd::to_stringと将来的にはより多くのオーバーロードを持つ可能性があります。

3
Davis Herring

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;
} 
2
Fibbles