Namespaces
Variants

std:: assignable_from

From ru.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 , может быть присвоено 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 выражениях концепций стандартной библиотеки, должны быть equality-preserving (если не указано иное).

Примечания

Присваивание не обязано быть тотальной функцией. В частности, если присваивание некоторому объекту x может привести к изменению другого объекта y , то x = y вероятно не принадлежит области определения = . Обычно это происходит, если правый операнд прямо или косвенно принадлежит левому операнду (например, при работе с умными указателями на узлы в узловой структуре данных, или с такими конструкциями как std:: vector < std:: any > ).

Пример

#include <atomic>
#include <concepts>
#include <string>
int main()
{
    // Обычное базовое использование, проверяет присваивание по lvalue-ссылке
    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>);
    // Фундаментальные типы не поддерживают присваивание rvalue
    static_assert(!std::is_assignable_v<int, int>);
    static_assert(!std::assignable_from<int, int>);
    // std::assignable_from не принимает все допустимые выражения присваивания:
    // присваивание по rvalue-ссылке
    static_assert(std::is_assignable_v<std::string&&, std::string>);
    static_assert(!std::assignable_from<std::string&&, std::string>);
    // присваивание rvalue
    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]

Смотрите также

проверяет, имеет ли тип оператор присваивания для конкретного аргумента
(шаблон класса)