Skip to content

Latest commit

 

History

History
117 lines (86 loc) · 3.98 KB

037-cpp17-core-std-byte.md

File metadata and controls

117 lines (86 loc) · 3.98 KB

std::byte : バイトを表現する型 {#std.byte}

C++17では、バイトを表現する型が入った。ライブラリでもあるのだがコア言語で特別な型として扱われている。

バイトとはC++のメモリーモデルにおけるストレージの単位で、C++においてユニークなアドレスが付与される最小単位だ。C++の規格はいまだに1バイトが具体的に何ビットであるのかを規定していない。これは過去にバイトのサイズが8ビットではないアーキテクチャーが存在したためだ。

バイトのビット数は<climits>で定義されているプリプロセッサーマクロ、CHAR_BITで知ることができる。

C++17では、1バイトはUTF-8の8ビットの1コード単位をすべて表現できると規定している。

std::byte型は、生のバイト列を表すための型として使うことができる。生の1バイトを表すにはunsigned char型が慣習的に使われてきたが、std::byte型は生の1バイトを表現する型として、新たにC++17で追加された。複数バイトが連続するストレージは、unsigned charの配列型、もしくはstd::byteの配列型として表現できる。

std::byte型は、<cstddef>で以下のように定義されている。

namespace std
{
    enum class byte : unsigned char { } ;
}

std::byteはライブラリとしてscoped enum型で定義されている。これにより、他の整数型からの暗黙の型変換が行えない。

0x12std::byte型の変数は以下のように定義できる。

int main()
{
    std::byte b{0x12} ;
}

std::byte型の値がほしい場合は、以下のように書くことができる。

int main()
{
    std::byte b{} ;

    b = std::byte( 1 ) ;
    b = std::byte{ 1 } ;
    b = static_cast< std::byte >( 1 ) ;
    b = static_cast< std::byte >( 0b11110000 ) ;
}

std::byte型は他の数値型からは暗黙に型変換できない。これによりうっかりと型を取り違えてバイト型と他の型を演算してしまうことを防ぐことができる。

int main()
{
    // エラー、()による初期化はint型からの暗黙の変換が入る
    std::byte b1(1) ;

    // エラー、=による初期化はint型からの暗黙の変換が入る
    std::byte b2 = 1 ;

    std::byte b{} ;

    // エラー、operator =によるint型の代入は暗黙の変換が入る
    b = 1 ;
    // エラー、operator =によるdouble型の代入は暗黙の変換が入る
    b = 1.0 ;
}

std::byte型は{}によって初期化するが、縮小変換を禁止するルールにより、std::byte型が表現できる値の範囲でなければエラーとなる。

たとえば、今std::byteが8ビットで、最小値が0、最大値が255の環境だとする。

int main()
{
    // エラー、表現できる値の範囲ではない
    std::byte b1{-1} ;
    // エラー、表現できる値の範囲ではない
    std::byte b2{256} ;
}

std::byteは内部のストレージをバイト単位でアクセスできるようにするため、規格上charと同じような配慮が行われている。

int main()
{
    int x = 42 ;

    std::byte * rep = reinterpret_cast< std::byte * >(&x) ;
}

std::byteは一部の演算子がオーバーロードされているので、通常の整数型のように使うことができる。ただし、バイトをビット列演算するのに使う一部の演算子だけだ。

具体的には、以下に示すシフト、ビットOR, ビット列AND, ビット列XOR, ビット列NOTだ。

<<= << 
>>= >>
|=  |
&=  &
^=  ^
~

四則演算などの演算子はサポートしていない。

std::byteはstd::to_integer<IntType>(std::byte)により、IntType型の整数型に変換できる。

int main()
{
    std::byte b{42} ;

    // int型の値は42
    auto i = std::to_integer<int>(b) ;
}