命名空间
变体
操作

std::assignable_from (自 C++20 起)

来自 cppreference.com
< cpp‎ | concepts
定义在头文件 <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 是一个非 const xvalue,它引用 lcopy(即,赋值是一个自移动赋值),
    • 如果 rhs 是一个 glvalue
      • 如果它是非 const xvalue,则它引用的对象处于有效但未指定的狀態;
      • 否则,它引用的对象不会被修改;

[编辑] 相等性保留

在标准库概念的 requires 表达式 中声明的表达式需要是 保持相等性 的(除非另有说明)。

[编辑] 注释

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

[编辑] 示例

#include <atomic>
#include <concepts>
#include <string>
 
int main()
{
    // Normal basic usage, checks lvalue reference assignment
    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>);
 
    // Fundamental types don't support assignment to an rvalue
    static_assert(!std::is_assignable_v<int, int>);
    static_assert(!std::assignable_from<int, int>);
 
    // std::assignable_from doesn't accept all valid assignment expressions:
 
    // rvalue reference assignment
    static_assert(std::is_assignable_v<std::string&&, std::string>);
    static_assert(!std::assignable_from<std::string&&, std::string>);
 
    // rvalue assignment
    static_assert(std::is_assignable_v<std::string, std::string>);
    static_assert(!std::assignable_from<std::string, std::string>);
 
    // std::atomic::operator= returns by value
    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]

[编辑] 另请参见

检查类型是否具有针对特定参数的赋值运算符
(类模板) [编辑]