在gcc 6中实现std::unique_ptr<T[]>::reset

8
自GCC 6以来,在C++中,unique_ptr<T[]>的声明/定义中的reset方法(不是仅接受nullptr_t的方法)如下所示:
template <typename _Up,
            typename = _Require<
              __or_<is_same<_Up, pointer>,
                    __and_<is_same<pointer, element_type*>,
                           is_pointer<_Up>,
                           is_convertible<
                             typename remove_pointer<_Up>::type(*)[],
                             element_type(*)[]
                           >
                    >
              >
           >>
  void
  reset(_Up __p) noexcept
  {
using std::swap;
swap(std::get<0>(_M_t), __p);
if (__p != nullptr)
  get_deleter()(__p);
  }

这个实现在某些时候被更改以实现N4089。根据该文档:

这个函数的行为与主模板的reset成员相同,只是它不参与重载决议,除非

Upointer类型相同,或者

pointerelement_type*类型相同,U是指针类型V*,且V(*)[]可以转换为element_type(*)[]

让我们考虑以下例子:

std::unique_ptr<const char []> ptr1;
std::unique_ptr<char []> ptr2(new char[5]);
ptr1 = std::move(ptr2);

自版本6起,GCC会产生一个错误,抱怨它无法使用const char*&char*&调用std::swap。由于char[]可以转换为const char[],所以reset方法在重载决议中发生,但是自然地,std::swap需要两个相同类型的引用。
这被认为是正确的行为吗?如果是,那么为什么?如果我可以将char[]隐式转换为const char[],为什么不能对unique_ptr执行相同的操作?

3
似乎是gcc的一个bug,已提交77987 - Barry
1
看起来 Jon Wakely 已经在修复它了。 - Barry
太好了!原来真的是一个bug。感谢@Barry报告。我即将关闭这个问题。 - user7020241
1个回答

0

所以这似乎是gcc libstdc++中的一个bug。 @Barry已经报告了它:77987


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接