Namespaces
Variants

std:: assignable_from

From cppreference.net
定义于头文件 <concepts>
template < class LHS, class RHS >

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

} ;
(C++20 起)

概念 assignable_from<LHS, RHS> 规定了由 RHS 指定的类型和值类别的表达式,可以被赋值给由 LHS 指定的类型的左值表达式。

目录

语义要求

给定

  • lhs ,一个左值,引用对象 lcopy ,使得 decltype ( ( lhs ) ) LHS
  • rhs ,一个表达式,使得 decltype ( ( rhs ) ) RHS
  • rcopy ,一个与 rhs 相等但不同的对象,

assignable_from<LHS, RHS> 仅在以下情况下成立:

  • std:: addressof ( lhs = rhs ) == std:: addressof ( lcopy ) (即赋值表达式产生指代左操作数的左值);
  • lhs = rhs 求值后:
    • lhs 等于 rcopy ,除非 rhs 是指向 lcopy 的非 const 右值引用(即该赋值是自移动赋值);
    • rhs 是泛左值:
      • 若其为非 const 右值引用,则其所指对象处于有效但未指定的状态;
      • 否则,其所指对象未被修改;

等值保持性

标准库概念的 requires 表达式 中声明的表达式必须满足 等值保持 要求(除非另有说明)。

注释

赋值不必是全域函数。特别地,如果对某个对象 x 的赋值可能导致其他对象 y 被修改,那么 x = y 很可能不在 = 的定义域内。这种情况通常发生在右操作数被左操作数直接或间接拥有时(例如,使用基于节点的数据结构中的智能指针,或类似 std:: vector < std:: any > 的情况)。

示例

#include <atomic>
#include <concepts>
#include <string>
int main()
{
    // 常规基础用法,检查左值引用赋值
    static_assert(std::is_assignable_v<int&, int>);
    static_assert(std::assignable_from<int&, int>);
    static_assert(std::is_assignable_v<std::string&, std::string>);
    static_assert(std::assignable_from<std::string&, std::string>);
    // 基础类型不支持向右值赋值
    static_assert(!std::is_assignable_v<int, int>);
    static_assert(!std::assignable_from<int, int>);
    // std::assignable_from 不接受所有有效的赋值表达式:
    // 右值引用赋值
    static_assert(std::is_assignable_v<std::string&&, std::string>);
    static_assert(!std::assignable_from<std::string&&, std::string>);
    // 右值赋值
    static_assert(std::is_assignable_v<std::string, std::string>);
    static_assert(!std::assignable_from<std::string, std::string>);
    // std::atomic::operator= 按值返回
    static_assert(std::is_assignable_v<std::atomic<int>&, int>);
    static_assert(!std::assignable_from<std::atomic<int>&, int>);
}

参考文献

  • C++23 标准 (ISO/IEC 14882:2024):
  • 18.4.8 概念 assignable_from [concept.assignable]
  • C++20 标准 (ISO/IEC 14882:2020):
  • 18.4.8 概念 assignable_from [concept.assignable]

参见

检查类型是否具有特定参数的赋值运算符
(类模板)