Here
是来自GCC的测试文件,
live demo
struct do_nothing
{
template <class T>
void operator()(T*) {}
};
int
main()
{
int i = 0;
std::unique_ptr<int, do_nothing> p1(&i);
std::unique_ptr<int> p2;
static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, ""); // note ! here.
}
std::is_assignable
如果表达式
std::declval<T>() = std::declval<U>()
在未计算的上下文中格式良好,提供的成员常量值等于true。否则,值为假。访问检查的执行方式就像来自与这两种类型无关的上下文一样。
std::declval
:
template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;
返回类型为
T&&
除非
T
是(可能是符合cv的)void,在这种情况下返回类型是t。
让我们来看一看
MoveAssignOnly
:
struct MoveAssignOnly {
MoveAssignOnly &operator=(MoveAssignOnly &) = delete;
MoveAssignOnly &operator=(MoveAssignOnly &&) = default;
};
int main()
{
static_assert(
not std::is_assignable<MoveAssignOnly, MoveAssignOnly>::value, "");
}
live demo
:
error: static_assert failed due to requirement '!std::is_assignable<MoveAssignOnly, MoveAssignOnly>::value'
对,
它无法编译,因为它提供了一个移动分配
让我们回到
gcc's test file
和
std::unique_ptr
. 正如我们所知,
std::unique_ptr
also has move assignments
.
然而,不像
struct MoveAssignOnly
,
static_assert(!std::is_assignable<decltype(p2), decltype(p1)>::value, "");
(更清楚地说,
static_assert(!std::is_assignable<std::unique_ptr<int>, std::unique_ptr<int, do_nothing>>::value, "");
编译得很愉快。
我一直在为libcxx实现
unique_ptr
很长一段时间,但仍然无法弄清楚:如何才能
STD::UNIQUIGYPTR
是
不可转让的
(
! is_assignable
当
STD::UNIQUIGYPTR
提供移动工作分配?