名前空間
変種
操作

std::shift_left, std::shift_right

From cppreference.com
< cpp‎ | algorithm
 
 
アルゴリズムライブラリ
制約付きアルゴリズムとRangeアルゴリズム (C++20)
制約付きアルゴリズム、例: ranges::copy, ranges::sort, ...
実行ポリシー (C++17)
シーケンスを変更しない操作
一括操作
(C++17)
検索操作
(C++11)                (C++11)(C++11)

シーケンスを変更する操作
コピー操作
(C++11)
(C++11)
スワップ操作
変換操作
生成操作
削除操作
順序変更操作
(C++17まで)(C++11)
shift_leftshift_right
(C++20)(C++20)
サンプリング操作
(C++17)

ソートおよび関連操作
パーティション操作
ソート操作
二分探索操作
(パーティション化された範囲)
集合操作 (ソート済み範囲)
マージ操作 (ソート済み範囲)
ヒープ操作
最小/最大操作
(C++11)
(C++17)
辞書順比較操作
順列操作
Cライブラリ
数値演算
未初期化メモリに対する操作
 
ヘッダー <algorithm> で定義
template< class ForwardIt >

constexpr ForwardIt shift_left( ForwardIt first, ForwardIt last,
                                typename std::iterator_traits<ForwardIt>::

                                    difference_type n );
(1) (C++20以降)
template< class ExecutionPolicy, class ForwardIt >

ForwardIt shift_left( ExecutionPolicy&& policy,
                      ForwardIt first, ForwardIt last,
                      typename std::iterator_traits<ForwardIt>::

                          difference_type n );
(2) (C++20以降)
template< class ForwardIt >

constexpr ForwardIt shift_right( ForwardIt first, ForwardIt last,
                                 typename std::iterator_traits<ForwardIt>::

                                     difference_type n );
(3) (C++20以降)
template< class ExecutionPolicy, class ForwardIt >

ForwardIt shift_right( ExecutionPolicy&& policy,
                       ForwardIt first, ForwardIt last,
                       typename std::iterator_traits<ForwardIt>::

                           difference_type n );
(4) (C++20以降)

範囲 [firstlast) 内の要素を n ポジションシフトします。

1) 範囲の先頭に向かって要素をシフトします。
  • n == 0 || n >= last - first の場合、効果はありません。
  • それ以外の場合、[0last - first - n) 内の各整数 i に対して、元々ポジション first + n + i にあった要素をポジション first + i に移動します。
移動は 0 から始まり、i の昇順で実行されます。
3) 範囲の末尾に向かって要素をシフトします。
  • n == 0 || n >= last - first の場合、効果はありません。
  • それ以外の場合、[0last - first - n) 内の各整数 i に対して、元々ポジション first + i にあった要素をポジション first + n + i に移動します。
ForwardItLegacyBidirectionalIterator の要件を満たしている場合、移動は last - first - n - 1 から始まり、i の降順で実行されます。
2,4) それぞれ (1) および (3) と同じですが、policy に従って実行され、移動は任意の順序で実行される場合があります。
これらのオーバーロードは、std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>true の場合にのみオーバーロード解決に参加します。

元の範囲に含まれるが新しい範囲に含まれない要素は、有効だが未指定の状態のままになります。

次のいずれかの条件が満たされる場合、動作は未定義です。

目次

[編集] パラメータ

first, last - シフトする要素の範囲を定義するイテレータのペア
n - シフトする位置の数
policy - 使用する 実行ポリシー
型要件
-
ForwardItLegacyForwardIterator の要件を満たさなければなりません。

[編集] 戻り値

1,2) 結果の範囲の末尾。
  • nstd::distance(first, last) より小さい場合、std::next(first, (std::distance(first, last) - n)) と等しいイテレータを返します。
  • それ以外の場合、first を返します。
3,4) 結果の範囲の先頭。
  • nstd::distance(first, last) より小さい場合、std::next(first, n) と等しいイテレータを返します。
  • それ以外の場合、last を返します。

[編集] 計算量

1,2) 最大 std::distance(first, last) - n 回の代入。
3,4) 最大 std::distance(first, last) - n 回の代入またはスワップ。

[編集] 例外

ExecutionPolicy というテンプレートパラメータを持つオーバーロードは、次のようにエラーを報告します。

  • アルゴリズムの一部として呼び出された関数の実行が例外をスローし、ExecutionPolicy標準ポリシー のいずれかである場合、std::terminate が呼び出されます。その他の ExecutionPolicy の場合、動作は実装定義です。
  • アルゴリズムがメモリの割り当てに失敗した場合、std::bad_alloc がスローされます。

[編集] 注釈

機能テストマクロ 規格 機能
__cpp_lib_shift 201806L (C++20) std::shift_left および std::shift_right

[編集]

#include <algorithm>
#include <iostream>
#include <string>
#include <type_traits>
#include <vector>
 
struct S
{
    int value{0};
    bool specified_state{true};
 
    S(int v = 0) : value{v} {}
    S(S const& rhs) = default;
    S(S&& rhs) { *this = std::move(rhs); }
    S& operator=(S const& rhs) = default;
    S& operator=(S&& rhs)
    {
        if (this != &rhs)
        {
            value = rhs.value;
            specified_state = rhs.specified_state;
            rhs.specified_state = false;
        }
        return *this;
    }
};
 
template<typename T>
std::ostream& operator<<(std::ostream& os, std::vector<T> const& v)
{
    for (const auto& s : v)
    {
        if constexpr (std::is_same_v<T, S>)
            s.specified_state ? os << s.value << ' ' : os << ". ";
        else if constexpr (std::is_same_v<T, std::string>)
            os << (s.empty() ? "." : s) << ' ';
        else
            os << s << ' ';
    }
    return os;
}
 
int main()
{
    std::cout << std::left;
 
    std::vector<S>           a{1, 2, 3, 4, 5, 6, 7};
    std::vector<int>         b{1, 2, 3, 4, 5, 6, 7};
    std::vector<std::string> c{"α", "β", "γ", "δ", "ε", "ζ", "η"};
 
    std::cout << "vector<S> \tvector<int> \tvector<string>\n";
    std::cout << a << "  " << b << "  " << c << '\n';
 
    std::shift_left(begin(a), end(a), 3);
    std::shift_left(begin(b), end(b), 3);
    std::shift_left(begin(c), end(c), 3);
    std::cout << a << "  " << b << "  " << c << '\n';
 
    std::shift_right(begin(a), end(a), 2);
    std::shift_right(begin(b), end(b), 2);
    std::shift_right(begin(c), end(c), 2);
    std::cout << a << "  " << b << "  " << c << '\n';
 
    std::shift_left(begin(a), end(a), 8); // has no effect: n >= last - first
    std::shift_left(begin(b), end(b), 8); // ditto
    std::shift_left(begin(c), end(c), 8); // ditto
    std::cout << a << "  " << b << "  " << c << '\n';
 
//  std::shift_left(begin(a), end(a), -3); // UB, e.g. segfault
}

実行結果の例

vector<S>       vector<int>     vector<string>
1 2 3 4 5 6 7   1 2 3 4 5 6 7   α β γ δ ε ζ η
4 5 6 7 . . .   4 5 6 7 5 6 7   δ ε ζ η . . .
. . 4 5 6 7 .   4 5 4 5 6 7 5   . . δ ε ζ η .
. . 4 5 6 7 .   4 5 4 5 6 7 5   . . δ ε ζ η .

[編集] 関連項目

(C++11)
要素の範囲を新しい場所にムーブする
(関数テンプレート) [編集]
要素の範囲を逆順で新しい場所にムーブする
(関数テンプレート) [編集]
範囲内の要素の順序を回転させる
(関数テンプレート) [編集]
範囲内の要素をシフトする
(アルゴリズム関数オブジェクト)[編集]
English 日本語 中文(简体) 中文(繁體)