Compilation error time: 0 memory: 3432 signal:0
prog.cpp: In function ‘int main()’:
prog.cpp:29:112: error: cannot dynamic_cast ‘(& v.std::vector<_Tp, _Alloc>::operator[]<std::unique_ptr<Base>, std::allocator<std::unique_ptr<Base> > >(0u))->std::unique_ptr<_Tp,
_Dp>::get<Base, std::default_delete<Base> >()’ (of type ‘std::unique_ptr<Base>::pointer {aka struct Base*}’) to type ‘class std::unique_ptr<Derived>’ (target is not pointer or reference)
std::cout << v[0]->x << " then " << v[1]->x << "then " << dynamic_cast<std::unique_ptr<Derived>>(v[0].get())->y;
Apologies for the wideness, thats the message I'm getting, my question is why does the orignal one error and fundamentally why cannot i cast from unique<T> to unique<U>?
You can't cast from unique<T> to unique<U> because unique<U> doesn't define a constructor to allow it and unique<T> doesn't provide a cast operator to allow it. For templates in general this is true, but especially for smart pointer classes like unique_ptr you will definitely not want more than one instance thinking it owns a pointer.
Remember, even if the wrapped types in two containers are compatible, the two containers themselves may not be compatible if they don't provide convenience casting support. I am guessing you're use to Java's Generics? They're nothing like C++ Templates, even though they look the same.
Thanks for that. Would an std::move be used somehow?
I was confused with the wrapped typed influencing the container type, but as you said they don't.
would this work with a shared_ptr, out of curiosity?
Nah not used to Java just trying out some of the new C++11 features and was hoping that would naively work. Now trying to figure out why, so I an understand it.
How does the dynamic_cast work? What goes on behind the scenes?
dynamic_cast doesn't care about what's in the objects you're casting, it only cares about the inheritance relationship between them. There is no inheritance relationship between unique<T> and unique<U>, in fact they're completely independent classes even though they came from the same template, so there's no way to cast between them.
And you wouldn't want a std::move to happen, because then your original unique_ptr would no longer refer to an object, and what would the rest of your code do? Let the greedy guy take it and leave?
std::unique_ptr<> holds the sole ownership of a managed object. Therefore, two different std::unique_ptr<> instances can't manage the same object; and dynamic cast semantics will not work with unique pointers.
We can cast the reference to the object held by a std::unique_ptr<> though - creation of a new unique pointer is not required. If the cast succeeds, we get a reference (with a different static type) to the same object; if it fails, an exception is thrown.