最終更新日時(UTC):
が更新

履歴 編集

(符号付き)size_tリテラルのためのサフィックス [P0330R8](C++23)

このページはC++23に採用された言語機能の変更を解説しています。

のちのC++規格でさらに変更される場合があるため関連項目を参照してください。

概要

C++23では、符号なし整数型size_tに対応する符号付き整数型を表すリテラルのzおよびZサフィックスを追加する。符号なしを表すuおよびUサフィックスをともに使用することでsize_t型のリテラルを記述できる。

auto a = 10z;  // size_tに対応する符号付き整数型
auto b = 10uz; // size_t型
auto c = 10UZ; // size_t型 (大文字でも同じ意味)
auto d = 10zu; // size_t型 (uとzは順不同)

この機能が必要になった背景・経緯

コンテナの要素数や普遍的なサイズを表す型としてsize_tは広く使用されてきたが、それを表すリテラル表現がなかったために、いくつかのケースで不便だった。

コンテナをfor文で回す際の初期値

std::vector<int> v{0, 1, 2, 3};

// case 1
for (auto i = 0u, s = v.size(); i < s; ++i) {}

// case 2
for (auto i = 0, s = v.size(); i < s; ++i) {}

// case 3
for (auto i = 0uz, s = v.size(); i < s; ++i) {}

ここでのcase 1では、0uunsigned int型リテラルとなり、size_t型が64ビットとして定義される場合に、size_t型をunsigned int型に丸めるために警告が出力される可能性がある。

case 2はコンパイルエラーとなる。

case 3はC++23で導入するsize_t型リテラルを使用するため、問題なく動作する。

min/maxに指定する2つの値の型

std::size_t size = ;

// case 1
std::size_t clamped_size = std::max(0, std::min(54, size));

// case 2
std::size_t clamped_size = std::max(0uz, std::min(54uz, size));

case 1はコンパイルエラーとなる。std::min()std::max()は2つの引数が同じ型であることを期待するため、int型の値とsize_t型の値の2つ渡そうとするとコンパイルエラーとなる。std::max<std::size_t>(a, b)のようにテンプレート引数を明示的に指定する回避方法もある。

case 2はC++23で導入するsize_t型リテラルを使用するため、問題なく動作する。

関連項目

参照