descargar book c++ c++11 c++17 unique-ptr

book - c++17 pdf



Puntero Ășnico no movible de C++ 17 (3)

Bienvenido al mundo de la deducción de tipos en C ++. Tratar

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

o

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

en lugar. Esta conferencia puede ser útil: https://www.youtube.com/watch?v=wQxj20X-tIU

Me encontré con esta respuesta Impedir el movimiento de un unique_ptr C ++ 11 . Sin embargo, al intentarlo en un compilador en línea, esto funciona con C ++ 11 (error del compilador std::move ) pero con C ++ 17, veo que el std::move continuación es exitoso. ¿No debería el compilador lanzar un error en esa línea? Además, si alguna semántica ha cambiado en C ++ 17, ¿cuál es la forma correcta de crear un unique_ptr no movible en C ++ 17 y en adelante?

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

Puedes probarlo en línea here .


Tenga en cuenta que p se declara como tipo sin referencia, la parte const del argumento scoped_ptr<int>(new int(5)) se ignora en la deducción de tipo. Entonces, el resultado de la deducción de tipo para p es std::unique_ptr<int> , no const std::unique_ptr<int> (es decir, scoped_ptr<int> como esperaba).

Lo que quieras podría ser

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


p no es const . Vea here para que falle como usted espera.

auto deduce como una template<class T>void foo(T) hace. T nunca se deduce como const , y tampoco lo es auto p= .

Mientras tanto, la línea auto p = funciona porque la compilaste en el modo c ++ 17 . En c ++ 11 no se compila . Esto se debe a que los valores varían en 17; Algunos llaman a la diferencia garantizada elision.

Si quieres un único ptr inmóvil:

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

una alternativa podría ser tomar un ptr único con un destructor inmóvil.

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

Pero no estoy seguro si eso funcionará.