名前空間
変種
操作

std::ranges::size

From cppreference.com
< cpp‎ | ranges
 
 
Rangesライブラリ
Rangeアダプタ
 
ヘッダ <ranges> で定義
ヘッダ <iterator> で定義
inline namespace /* 未指定 */ {

    inline constexpr auto size = /* 未指定 */;

}
(C++20以降)
(カスタマイズポイントオブジェクト)
呼び出しシグネチャ
template< class T >

    requires /* 以下を参照 */

constexpr auto size( T&& t );
(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::size(E)decay-copy (size(t))(until C++23)auto(size(t))(since C++23) に式同値です。
  • それ以外の場合で、以下のすべての条件が満たされる場合、ranges::size(E)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 は以下をモデル化します。

それ以外の場合、__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 を禁止する仕組みがあります。 その仕組みは削除されました。

[編集] 関連項目

rangeのサイズと等しい符号付き整数を返す
(カスタマイゼーションポイントオブジェクト)[編集]
rangeが定数時間でそのサイズを知っていることを規定する
(コンセプト) [編集]
イテレータと番兵 (sentinel) の間の距離、またはRangeの始点と終点の間の距離を返す
(アルゴリズム関数オブジェクト)[編集]
(C++17)(C++20)
コンテナまたは配列のサイズを返す
(関数テンプレート) [編集]
English 日本語 中文(简体) 中文(繁體)