最終更新日時: 2025年07月09日 00時33分39秒 (JST)
Akira Takahashi が更新

履歴 編集

class template
<ranges>

# std::ranges::single_view(C++20)

    namespace std::ranges {
      template<copy_constructible T>
        requires is_object_v<T>
      class single_view : public view_interface<single_view<T>> { …… }; // (1) C++20
      template<move_constructible T>
        requires is_object_v<T>
      class single_view : public view_interface<single_view<T>> { …… }; // (1) C++23

      namespace views {
        inline constexpr /*unspecified*/ single = /*unspecified*/; // (2)
      }
    }

## 概要

- (1): 値を要素1つのRangeに見せる`view`
- (2): `single_view`を生成するカスタマイゼーションポイントオブジェクト

### Rangeコンセプト

borrowed | sized | output | input | forward | bidirectional | random_access | contiguous | common | viewable | view
--- | --- | --- | --- | --- | --- | --- | --- | --- | --- | ---
| ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○ | ○

## テンプレートパラメータ制約

- (1) :
  - C++20 : 型`T`がコピー構築可能であること
  - C++23 : 型`T`がムーブ構築可能であること

## 効果

- 式`views::single(E)`の効果は`single_view<decay_t<decltype((E))>>(E)`と等しい。

## メンバ変数

名前 | 説明 | 対応バージョン
--- | --- | ---
`movable-box<T> value_` | 単一要素の値 | C++20

## メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`(constructor)` | コンストラクタ | C++20
`begin` | 先頭を指すイテレータを取得する | C++20
`end` | 番兵を取得する | C++20
`data` | 配列の先頭へのポインタを取得する | C++20

## 静的メンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`size` | 要素数を取得する | C++20
`empty` | Rangeが空かどうかを判定する | C++20

## 継承しているメンバ関数

名前 | 説明 | 対応バージョン
--- | --- | ---
`operator bool` | Rangeが空でないかどうかを判定する | C++20
`front` | 先頭要素への参照を取得する | C++20
`back` | 末尾要素への参照を取得する | C++20
`operator[]` | 要素へアクセスする | C++20
`cbegin` | 定数イテレータを取得する | C++23
`cend` | 定数イテレータ（番兵）を取得する | C++23

## 推論補助

名前 | 説明 | 対応バージョン
--- | --- | ---
`(deduction_guide)` | クラステンプレートの推論補助 | C++20

## 例

    #include <ranges>
    #include <iostream>

    int main() {
      using namespace std;

      for(int n : views::single(1)) {
        cout << n;
      }
    }

### 出力

    1

## 実装例

    namespace std::ranges {
      template<copy_constructible T>
        requires is_object_v<T>
      class single_view : public view_interface<single_view<T>> {
      private:
        copyable-box<T> value_;

      public:
        single_view() requires default_initializable<T> = default;
        constexpr explicit single_view(const T& t): value_(t) {
        }
        constexpr explicit single_view(T&& t): value_(t) {
        }
        template<class... Args>
          requires constructible_from<T, Args...>
        constexpr explicit single_view(in_place_t, Args&&... args): value_{in_place, forward<Args>(args)...} {
        }

        constexpr T* begin() noexcept {
          return data();
        }
        constexpr const T* begin() const noexcept {
          return data();
        }
        constexpr T* end() noexcept {
          return data() + 1;
        }
        constexpr const T* end() const noexcept {
          return data() + 1;
        }
        static constexpr size_t size() noexcept {
          return 1;
        }
        constexpr T* data() noexcept {
          return value_.operator->();
        }
        constexpr const T* data() const noexcept {
          return value_.operator->();
        }
      };

      template<class T>
        single_view(T) -> single_view<T>;
    }

## バージョン

### 言語

- C++20

### 処理系

- Clang: 13.0.0 ✅
- GCC: 10.1.0 ✅
- ICC: ?
- Visual C++: 2019 Update 10 ✅

## 参照

- N4861 24 Ranges library
- C++20 ranges
- P2367R0 Remove misuses of list-initialization from Clause 24 (本提案文書はC++20に遡って適用されている)