问题描述
我有一个类Base
和一个派生类Derived
。
函数从文件描述符读取对象并返回Base
对象:
std::unique_ptr<Base> readNextThing();
在某些地方,我需要将此函数的返回值向下转换为Derived。这很重要,因为输入的unique_ptr是一个右值引用,因此我们不复制指针,而是移动它。在这种特定的上下文中,如果它不是Derived
子类型的对象,我不介意被破坏,我只需要检测这种情况下向下转换的指针为空即可。
我可以做到:
template<typename T,typename U>
std::unique_ptr<T> dynamic_unique_cast(std::unique_ptr<U> && unique)
{
T * t = dynamic_cast<T*>(unique.get());
if(t) { unique.release(); } //Transfer ownership
return std::unique_ptr<T>(t);
}
和
std::unique_ptr<Derived> d = dynamic_unique_cast<Derived>(readNextThing());
解决方法
不幸的是,std::dynamic_pointer_cast
doesn't work on unique_ptr
-没有理由不能在右值unique_ptr
上运行,除了故障情况下的行为可能不是显而易见的。
如果这是一次性案例,则可以通过std::shared_ptr
进行操作,请注意它具有unique_ptr
中的隐式构造函数:
auto ptr = std::unique_ptr<Derived>(
std::dynamic_pointer_cast<Derived>(readNextThing()).release());
但是我认为您建议的实用程序功能更清晰。也许使用this solution中的那个?