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