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

履歴 編集

concept
<concepts>

std::assignable_from(C++20)

namespace std {
  template<class LHS, class RHS>
  concept assignable_from =
    is_lvalue_reference_v<LHS> &&
    common_reference_with<const remove_reference_t<LHS>&, const remove_reference_t<RHS>&> &&
    requires(LHS lhs, RHS&& rhs) {
      { lhs = std::forward<RHS>(rhs) } -> same_as<LHS>;
    };
}

概要

assignable_fromは、指定された型および値カテゴリRHSから左辺値LHSへ代入可能であることを表すコンセプトである。

モデル

まず、lhsdecltype((lhs))LHSであるようなlcopyオブジェクトを参照する左辺値(参照)、rhsdecltype((rhs))RHSであるような式、rcopyrhsと等値な別のオブジェクトとして定義する。

これらのlhs, rhs, lcopy, rcopyについて、以下の条件を満たす場合に限って、型LHS, RHSassignable_fromのモデルである。

  • addressof(lhs = rhs) ==addressof(lcopy)となる
  • lhs = rhs;という式の評価の後で以下のことが成り立っている
    • rhslcopyを参照する非const xvalueでない(ムーブが起こる自己代入ではない)場合
      • lhsrcopyと等値である
    • rhsが非const xvalueならば
      • rhsが参照するオブジェクトの状態は有効だが未規定
    • それ以外の場合で、rhsglvalueならば
      • rhsが参照するオブジェクトは変更されない

rhsprvalueの場合、2つめの条件のいずれにも該当しない。これはコピー省略等の最適化を考慮したものである。

備考

代入操作では、引数型の一部の値が本コンセプトが要求する構文・意味論的制約を必ずしも満たしていなくても構わない。特に、あるオブジェクトxへの代入操作によって別のオブジェクトyが変更される時、x, yはその場合の=の定義域に含まれない事がある。

あるLHS, RHSについてそのような個別の値が存在していたとしても、そのことはそのLHS, RHSassignable_fromのモデルとなることを妨げない。

#include <iostream>
#include <concepts>
#include <vector>
#include <memory>

template<typename LHS, typename RHS>
  requires std::assignable_from<LHS, RHS>
void f(const char* name, const char* arg) {
  std::cout << name << " is assignable from " << arg << std::endl;
}

template<typename LHS, typename RHS>
void f(const char* name, const char* arg) {
  std::cout << name << " is not assignable from " << arg << std::endl;
}

struct S {
  S& operator=(const S&) = default;
  S& operator=(S&&) = delete;
};

int main() {
  f<int&, short>("int&", "short");
  f<std::vector<int>&, std::vector<int>>("std::vector<int>&", "std::vector<short>");
  f<std::unique_ptr<int>&, std::unique_ptr<int>>("std::unique_ptr<int>&", "std::unique_ptr<int>");
  f<S&, S&>("S&", "S&");

  std::cout << "\n";

  f<std::unique_ptr<int>&, std::unique_ptr<int>&>("std::unique_ptr<int>&", "std::unique_ptr<short>&");
  f<S&, S>("S&", "S");
}

出力

int& is assignable from short
std::vector<int>& is assignable from std::vector<short>
std::unique_ptr<int>& is assignable from std::unique_ptr<int>
S& is assignable from S&

std::unique_ptr<int>& is not assignable from std::unique_ptr<short>&
S& is not assignable from S

バージョン

言語

  • C++20

処理系

関連項目

参照