gpt4 book ai didi

c++ - is_assignable 和 std::unique_ptr

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:36:27 24 4
gpt4 key购买 nike

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

If the expression std::declval<T>() = std::declval<U>() is well-formed in unevaluated context, provides the member constant value equal true. Otherwise, value is false. Access checks are performed as if from a context unrelated to either type.

std::declval :

template<class T>
typename std::add_rvalue_reference<T>::type declval() noexcept;

The return type is T&& unless T is (possibly cv-qualified) void, in which case the return type is 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'

是的,它无法编译,因为它提供了 move 分配

让我们回到 gcc's test filestd::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::unique_ptr怎么能当 ! is_assignable不可分配( std::unique_ptr )提供 move 任务?

最佳答案

p1p2 是不同的类型。与 shared_ptr 不同,unique_ptr 的删除器是指针类型的一部分。这意味着如果删除器类型不同, move 赋值运算符不允许您在两个 unique_ptr 之间进行赋值(甚至 move 赋值)。

unique_ptr 还提供了一个赋值运算符模板,它允许使用不同的删除器从 unique_ptr 的右值进行分配,但删除器必须是可分配的(参见 reference )。因此,您可以通过使删除器可分配来使静态断言触发:

struct do_nothing
{
template <class T>
void operator()(T*) {}

template <class T>
operator std::default_delete<T>() { return {}; }
};

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.
}

[Live example]

关于c++ - is_assignable 和 std::unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53882498/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com