Non-Movable C++17 Unique Pointer

  • A+

I came across this answer Prevent moving of a unique_ptr C++11. However while trying it out on a compiler online, this works with C++11(std::move compiler error) but with C++17, I'm seeing that the std::move below is successful. Shouldn't the compiler throw an error on that line? Also if some semantics have changed in C++17, what is the correct way to create a non movable unique_ptr in C++17 and onward.

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

You can try it online here.


p is not const. See here for it to fail the way you expect.

auto deduces like a template<class T>void foo(T) does. T is never deduced as const, and neither is auto p=.

Meanwhile, the auto p = line works because you compiled it in mode. In it does not compile. This is because how prvalues differ in 17; some call the difference guaranteed elision.

If you want an immobile unique 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 

an alternative might be to take a unique ptr with an immobile destroyer.

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>>; 

But I am uncertain if that will work.


:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: