不可移动的C++17唯一指针



我遇到了这个答案防止移动unique_ptr C++11。然而,当在编译器上在线尝试时,这适用于C++11(std::move编译器错误(,但对于C++17,我看到下面的std::move是成功的。编译器不应该在那一行抛出错误吗?此外,如果C++17中的某些语义发生了变化,那么在C++17及以后的版本中创建不可移动unique_ptr的正确方法是什么。

template <typename T>
using scoped_ptr = const std::unique_ptr<T>;
int main()
{
auto p = scoped_ptr<int>(new int(5));
auto p2 = std::move(p); // should be error?
std::cout << *p2 << std::endl; // 5
return 0;
}

你可以在这里在线试用。

p不是const。看看这里,它会以你期望的方式失败。

CCD_ 5像CCD_。T从未被推导为constauto p=也不是。

同时,auto p =行之所以有效,是因为您是在c++17模式下编译它的。在c++11中,它不进行编译。这是因为prvalues在17中的差异;有些人称这种差异是有保证的省略。

如果你想要一个固定的唯一ptr:

template<class T, class D>
struct immobile_ptr:private std::unique_ptr<T, D>{
using unique_ptr<T>::operator*;
using unique_ptr<T>::operator->;
using unique_ptr<T>::get;
using unique_ptr<T>::operator bool;
// etc
// manually forward some ctors, as using grabs some move ctors in this case
};
template<class T, class...Args>
immobile_ptr<T> make_immobile_ptr(Args&&...args); // todo

另一种选择可能是用一个不动的驱逐舰携带一个独特的ptr。

template<class X>
struct nomove_destroy:std::destroy<T>{
nomove_destroy(nomove_destroy&&)=delete;
nomove_destroy()=default;
nomove_destroy& operator=(nomove_destroy&&)=delete;
};
template<class T>
using nomove_ptr=std::unique_ptr<T,nomove_destroy<T>>;

但我不确定这是否可行。

注意,p被声明为非引用类型,参数scoped_ptr<int>(new int(5))const部分在类型推导中被忽略。那么p的类型推导结果是std::unique_ptr<int>,而不是const std::unique_ptr<int>(即您所期望的scoped_ptr<int>(。

你想要的可能是

auto& p = scoped_ptr<int>(new int(5)); // p is of type const std::unique_ptr<int>& now

欢迎来到C++中类型推导的世界。尝试

auto & p = scoped_ptr<int>(new int(5));

auto && p = scoped_ptr<int>(new int(5));

相反。本次讲座可能会有所帮助:https://www.youtube.com/watch?v=wQxj20X-tIU

相关内容

  • 没有找到相关文章

最新更新