unique_ptr usage too unwieldy
Let me restate the problem, because it wasn't 100% clear to me from what you've written. I personally think you've left out a bit too much code. I'll state my assumptions of what is going on, but ideally this should be clear from what is posted. Firstly, I assume EntityDatabase is a class, not a namespace. Secondly, I assume ItemDatabase is declared as something like:

EntityDatabase&lt;Item&gt; ItemDatabase;


Further, I assume you have some kind of inheritance hierarchy that looks something like:

class Item
{
    Item();
    virtual ~Item();
    //....
}

class Weapon : public Item
{ 
    //...
}

class Armor : public Item
{
    //...
}


The problem then is that ItemDatabase.find(...) (I assume it's meant to be ., not ::) will return a std::unique_ptr&lt;Item&gt; when you want a std::unique_ptr&lt;Weapon&gt; or some other derived class of Item.

This seems less a problem of unique_ptr and more the fact that you're kind of abusing polymorphism. Let's assume you didn't return a unique_ptr, just a normal Item*:

template &lt;typename DataType&gt;
DataType* EntityDatabase&lt;DataType&gt;::find(EntityId const&amp; entityId)


The only thing that would change then is that armor_ would be declared as Armor* instead of std::unique_ptr&lt;Armor&gt;, so it would become:

 armor_ = static_cast&lt;Armor*&gt;(ItemDatabase::find(armorId));


Hence, the only things that really change are the calls to release and reset. This is not significantly less ugly than what is already there. If armour_ were declared as std::unique_ptr&lt;Item&gt; then you could of course do the following:

armor_ = std::move(ItemDatabase::find(armorId));


Again, this is all built on a lot of assumptions since there is quite a bit of context missing.

For fixes, I suppose the options are:


Leave it as is. It's fairly ugly, but not that much uglier than the code you'd have for raw pointers.
Fix your inheritance hierarchy. The fact that you're having to cast things back and forth suggests that perhaps polymorphism isn't the correct solution here. Does each item need to know its specific type? Is there a virtual function you can add to Item that will fix this? I don't know, there's not enough context from the code you've posted.
Finally, make a function to limit the uglyness to one spot:

template &lt;typename T, typename U&gt;
void recast(std::unique_ptr&lt;T&gt;&amp; ptr1, std::unique_ptr&lt;U&gt;&amp;&amp; ptr2)
{
    static_assert(std::is_base_of&lt;U, T&gt;::value, "U is not a base type of T");
    ptr1.reset(static_cast&lt;T*&gt;(ptr2.release()));
}

....
auto armorId  = getValue&lt;EntityId&gt;(jsonInventory, "Armor");
recast(armor_, ItemDatabase::find(armorId));



This is still pretty ugly, but if used often, might be slightly less offensive.