std::ranges::size
| ヘッダ <ranges> で定義 |
||
| ヘッダ <iterator> で定義 |
||
| inline namespace /* 未指定 */ { inline constexpr auto size = /* 未指定 */; |
(C++20以降) (カスタマイズポイントオブジェクト) |
|
| 呼び出しシグネチャ |
||
| template< class T > requires /* 以下を参照 */ |
(C++20以降) | |
定数時間で t の要素数を計算します。
t が (必要に応じて 具体化された) 結果オブジェクトを示す 完全式を E とし、E の型を T とします。
Tが未知の境界を持つ配列の場合、ranges::size(E) は不定形です。- それ以外の場合で、
Tが配列型の場合、ranges::size(E) は decay-copy (std::extent_v<T>)(until C++23)auto(std::extent_v<T>)(since C++23) に式同値です。 - それ以外の場合で、以下のすべての条件が満たされる場合、ranges::size(E) は decay-copy (t.size())(until C++23)auto(t.size())(since C++23) に式同値です。
- ranges::disable_sized_range<std::remove_cv_t<T>> は false です。
- decay-copy (t.size())(until C++23)auto(t.size())(since C++23) は有効な整数型のような式です。
- それ以外の場合で、以下のすべての条件が満たされる場合、ranges::size(E) は decay-copy (size(t))(until C++23)auto(size(t))(since C++23) に式同値です。
-
Tはクラス型または列挙型です。 - ranges::disable_sized_range<std::remove_cv_t<T>> は false です。
- decay-copy (size(t))(until C++23)auto(size(t))(since C++23) は有効な整数型のような式です。ここで
sizeの意味は、引数依存探索のみを実行した場合と同様に確立されます。
-
- それ以外の場合で、以下のすべての条件が満たされる場合、ranges::size(E) は
to-unsigned-like(ranges::end(t) - ranges::begin(t)) に式同値です。-
Tはforward_rangeをモデル化します。 - ranges::begin(t) の型を
Iとし、ranges::end(t) の型をSとすると、sized_sentinel_for<S, I> およびforward_iterator<I> の両方がモデル化されます。 -
to-unsigned-like(ranges::end(t) - ranges::begin(t)) は有効な式です。
-
- それ以外の場合、ranges::size(E) は不定形です。
上記のような診断可能な不定形ケースは、ranges::size(E) がテンプレートインスタント化の直接のコンテキストに現れる場合、置換失敗につながります。
目次 |
カスタマイゼーションポイントオブジェクト
ranges::size という名前は カスタム化ポイントオブジェクト を表します。これは、リテラルな semiregular クラス型の const 関数オブジェクトです。説明のために、その型の cv 修飾されていないバージョンを __size_fn と表記します。
__size_fn のすべてのインスタンスは等価です。同じ引数に対して呼び出された異なる __size_fn 型のインスタンスの呼び出し効果は、インスタンスを表す式が左辺値か右辺値か、また const 修飾されているか否かに関わらず同等です (ただし、volatile 修飾されたインスタンスは呼び出し可能である必要はありません)。したがって、ranges::size は自由にコピーでき、そのコピーは相互に交換可能に使用できます。
型 Args... のセットが与えられた場合、std::declval<Args>()... が上記の ranges::size への引数の要件を満たす場合、__size_fn は以下をモデル化します。
- std::invocable<__size_fn, Args...>,
- std::invocable<const __size_fn, Args...>,
- std::invocable<__size_fn&, Args...>、および
- std::invocable<const __size_fn&, Args...>.
それ以外の場合、__size_fn の関数呼び出し演算子のいずれもオーバーロード解決に参加しません。
[編集] 注釈
ranges::size(e) が式 e に対して有効な場合、戻り値の型は 整数型のような型になります。
C++20 標準では、基となる size 関数呼び出しが prvalue を返す場合、戻り値は一時オブジェクトからムーブ構築されることを要求しています。すべての実装では、代わりに prvalue を直接返しています。この要件は、C++20 後に提案された P0849R8 によって、実装に合わせるように修正されています。
式 ranges::distance(e) は、範囲 e のサイズを決定するためにも使用できます。ranges::size(e) とは異なり、ranges::distance(e) は e がサイズ指定のない範囲であっても機能しますが、その場合線形時間計算量がかかります。
[編集] 例
#include <iostream> #include <ranges> #include <type_traits> #include <vector> int main() { auto v = std::vector<int>{}; std::cout << "ranges::size(v) == " << std::ranges::size(v) << '\n'; auto il = {7}; // std::initializer_list std::cout << "ranges::size(il) == " << std::ranges::size(il) << '\n'; int array[]{4, 5}; // array has a known bound std::cout << "ranges::size(array) == " << std::ranges::size(array) << '\n'; static_assert(std::is_signed_v<decltype(std::ranges::size(v))> == false); }
出力
ranges::size(v) == 0 ranges::size(il) == 1 ranges::size(array) == 2
[編集] 不具合報告
以下の動作変更を伴う欠陥報告が、以前に公開されたC++標準に遡って適用されました。
| DR | 適用対象 | 公開された動作 | 正しい動作 |
|---|---|---|---|
| P2602R2 | C++20 | ADL によって見つかる一部の非メンバ size を禁止する仕組みがあります。 |
その仕組みは削除されました。 |
[編集] 関連項目
| (C++20) |
rangeのサイズと等しい符号付き整数を返す (カスタマイゼーションポイントオブジェクト) |
| (C++20) |
rangeが定数時間でそのサイズを知っていることを規定する (コンセプト) |
| (C++20) |
イテレータと番兵 (sentinel) の間の距離、またはRangeの始点と終点の間の距離を返す (アルゴリズム関数オブジェクト) |
| (C++17)(C++20) |
コンテナまたは配列のサイズを返す (関数テンプレート) |