Skip to content

Files

138 lines (107 loc) · 3.08 KB

exchange.md

File metadata and controls

138 lines (107 loc) · 3.08 KB

exchange

  • utility[meta header]
  • std[meta namespace]
  • function template[meta id-type]
  • cpp14[meta cpp]
namespace std {
  template <class T, class U=T>
  T exchange(T& obj, U&& new_val);           // C++14

  template <class T, class U=T>
  constexpr T exchange(T& obj, U&& new_val); // C++20
}

概要

値を書き換え、書き換え前の値を返す。

効果

第1パラメータobjで受け取った変数への参照に、第2パラメータnew_valの値をムーブ代入し、代入前のobjの状態を返す。

以下と等価の効果を持つ:

T old_val = std::move(obj);
obj = std::forward<U>(new_val);
return old_val;
  • std::move[link move.md]
  • std::forward[link forward.md]

戻り値

この関数を呼び出す前の、第1パラメータobjの状態を返す。

備考

この関数は、std::atomic_exchange()関数の経験から導入された。

#include <iostream>
#include <utility>

int main()
{
  int state = 1;
  int before = std::exchange(state, 2);

  std::cout << "state : " << state << std::endl;
  std::cout << "before : " << before << std::endl;
}
  • std::exchange[color ff0000]

出力

state : 2
before : 1

コンテナを出力する例

#include <iostream>
#include <utility>
#include <vector>

template <class T>
void print_1(const std::vector<T>& v)
{
  // カンマ区切りでvectorを出力する。
  // 区切り文字は、各要素の後ではなく、前に置くと考える。
  // 最初の要素のみ区切り文字を出力しない。

  bool first = true;

  std::cout << '{';
  for (const T& x : v) {
    if (!std::exchange(first, false)) {
      std::cout << ',';
    }
    std::cout << x;
  }
  std::cout << '}' << std::endl;
}

// 別な書き方
template <class T>
void print_2(const std::vector<T>& v)
{
  const char* delimiter = "";

  std::cout << '{';
  for (const T& x : v) {
    std::cout << std::exchange(delimiter, ",") << x;
  }
  std::cout << '}' << std::endl;
}


int main()
{
  const std::vector<int> v = {1, 2, 3};
  print_1(v);
  print_2(v);
}
  • std::exchange[color ff0000]

出力

{1,2,3}
{1,2,3}

バージョン

言語

  • C++14

処理系

関連項目

参照