Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

understanding c++ move_constructible concept implementation

I've got the following implementation of the c++ concept move_constructible from cppreference

template<typename _Tp>
concept move_constructible =
    constructible_from<_Tp, _Tp> &&
    convertible_to<_Tp, _Tp>;

I don't get why this works. I presume any type can be converted to itself, so the second requirement is pointless (God, I must be very wrong about something). Also, for the first requirement I would have expected something like constructible_from<_Tp, _Tp&&> to check if the type can be constructed from rvalue-ref (thus, moved).

Please explain how this implementation works.

like image 747
DeltA Avatar asked Nov 22 '21 04:11

DeltA


1 Answers

Most traits/concepts automatically add && to the types of "source" arguments (things that are passed to functions, as in std::is_invocable, or constructed from, as in std::is_constructible).

I.e. constructible_from<A, B> is equivalent to constructible_from<A, B &&> (&& is automatically added to the second argument, but not to the first), and convertible_to<A, B> is equivalent to convertible_to<A &&, B>.

Note that if a type already includes &, adding && to it has no effect. So, while T and T && are equivalent here, T & is not.


This can be inferred from those traits/concepts being defined in terms of std::declval<T>(), which returns T &&.

For the reason why std::declval<T &>() returns T &, see reference collapsing.

like image 128
HolyBlackCat Avatar answered Oct 22 '22 11:10

HolyBlackCat