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]
См. также
|
(C++11)(C++11)(C++11) | проверяет, имеет ли тип оператор присваивания для заданного аргумента (шаблон класса) |
|
(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