• Class / Function / Type

      std::
    • Header file

      <>
    • Other / All

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

    履歴 編集

    customization point object
    <iterator>

    std::ranges::iter_move

    namespace std {
      namespace ranges {
        inline namespace /*unspecified*/ {
    
          inline constexpr /*unspecified*/ iter_move = /*unspecified*/;
        }
      }
    }
    

    概要

    iter_moveはイテレータを1つ受け取り、そのイテレータの参照する要素の値を移動(move)するカスタマイゼーションポイントオブジェクトである。

    効果

    iter_move(i)のように呼び出された時、以下のいずれかと等価

    1. 引数iの型がクラス型であるか列挙型であり、std::ranges::iter_move(本CPO)の宣言を含まず下記のiter_move関数宣言を含むコンテキストで、iter_move(i)が呼び出し可能ならばiter_move(i)

      void iter_move();
      

    2. *iが有効であり、*iの結果が左辺値であるならばstd::move(*i)

    3. *iが有効であり、*iの結果が右辺値であるならば*i

    4. それ以外の場合、呼び出しは不適格

    1のケースの場合に、呼び出されるiter_move()が移動しようとする値を変更する場合、プログラムは不適格(ただし、コンパイルエラーとならない可能性がある)。

    戻り値

    引数iの指す要素の(右辺値)参照、もしくはiの指す要素を移動した値

    例外

    上記「効果」節のそれぞれのケース毎に

    1. 呼び出されるiter_move()例外を投げるかに従う
    2. 引数iについての*演算子が例外を投げるかに従う
    3. 引数iについての*演算子が例外を投げるかに従う

    定数式に評価される条件

    1. 呼び出されるiter_move()が定数評価可能かに従う
    2. 引数iについての*演算子が定数評価可能かに従う
    3. 引数iについての*演算子が定数評価可能かに従う

    カスタマイゼーションポイント

    1. 引数iの型と同じ名前空間で、もしくはHidden friendsとして、非メンバiter_move()関数を定義しておく
    2. --
    3. --

    備考

    一見するとこのCPOは冗長であるように見えるが、イテレータiについての*iの結果がprvalueを返す(イテレータの要素型Tのオブジェクトをそのまま返す)場合に不要なキャストを回避することでより効率的なムーブ(コピー省略による直接構築)を行うことができる。

    イテレータを利用したジェネリックなアルゴリズムの実装においてイテレータの要素をムーブする必要がある場合には、std::move(*i)のようなコードを直接書くよりもこのCPOを使用したほうがより効率的になりうる。

    #include <iterator>
    #include <vector>
    #include <iostream>
    
    struct I {
      int n = 0;
    
      // Hidden friendsとして定義、prvalueを返す
      friend auto iter_move(I& self) -> I {
        return std::move(self);
      }
    
      I& operator*();
    };
    
    int main() {
      I i = {20};
    
      // ケース1の呼び出し
      I i2 = std::ranges::iter_move(i);
    
      std::cout << i2.n << std::endl;
    
      std::vector vec = {1, 2, 3, 4};
    
      // ケース2の呼び出し
      int n = std::ranges::iter_move(vec.begin());
    
      std::cout << n << std::endl; 
    }
    

    出力

    20
    1
    

    バージョン

    言語

    • C++20

    処理系

    参照