Just came from is_assignable and std::unique_ptr. @Angew tells me that because std::unique_ptr<int, do_nothing> and std::unique_ptr<int> are different types, so static_assert(not std::is_assignable<std::unique_ptr<int>, std::unique_ptr<int, do_nothing>>::value, "");. So, I tried:
template<typename T, typename D>
struct MoveAssignOnly_V2
{
MoveAssignOnly_V2&
operator=(MoveAssignOnly_V2&)
= delete;
MoveAssignOnly_V2&
operator=(MoveAssignOnly_V2&&) noexcept
{}
};
int main()
{
static_assert(not std::is_assignable_v<MoveAssignOnly_V2<int, float>,
MoveAssignOnly_V2<int, double>>);
}
Yes, because MoveAssignOnly_V2<int, float> and MoveAssignOnly_V2<int, double> are two different types, so they are not assignable.
But, when I add a a move ctor:
template<class U, class E>
MoveAssignOnly_V2(MoveAssignOnly_V2<U, E>&& m) noexcept {}
static_assert fail!(both gcc and clang).
Question here: Why does move constructor affects is_assignable?
Updated
The reason why I add this constructor is that I found std::unique_ptr have a
template< class U, class E >
unique_ptr( unique_ptr<U, E>&& u ) noexcept;
, which confuses me a little: how can it be not assignable now that it has such a ctor? so I tried add such ctor to MoveAssignOnly_V2 and post this question. The two answers are fine, however, still cannot explain why std::unique_ptr is not assignable when it has both move assignment and this templated constructor.