Spec-Zone.ru › C++

std::assignable_from

Определён в заголовочном файле <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, можно присвоить выражению lvalue, тип которого задан LHS.

Семантические требования

Пусть заданы

  • lhs — lvalue, ссылающееся на объект lcopy, такой что decltype((lhs)) является LHS,
  • rhs — выражение такое, что decltype((rhs)) является RHS,
  • rcopy — отдельный объект, равный rhs,

assignable_from<LHS, RHS> моделируется только в том случае, если

  • std::addressof(lhs = rhs) == std::addressof(lcopy) (то есть выражение присваивания возвращает lvalue, ссылающееся на левый операнд);
  • После вычисления lhs = rhs:
    • lhs равен rcopy, если только rhs не является неконстантным xvalue, ссылающимся на lcopy (то есть присваивание не является самоперемещающим присваиванием),
    • если rhs является glvalue:
      • Если это неконстантный 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]

См. также

is_assignableis_trivially_assignableis_nothrow_assignable
(C++11)(C++11)(C++11)
проверяет, имеет ли тип оператор присваивания для заданного аргумента
(шаблон класса)
is_assignable_typeis_trivially_assignable_typeis_nothrow_assignable_type
(C++26)(C++26)(C++26)
проверяет, имеет ли отражённый тип оператор присваивания для заданного аргумента
(функция)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/concepts/assignable_from

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API