动态多态类型扣除使用decltype
问题描述:
你能给我一个提示,如何使这段代码工作,因为我想要它?我想derived_t
为Derived
,但它总是Base
。动态多态类型扣除使用decltype
#include <iostream>
#include <string>
#include <memory>
struct Base {
virtual std::string me() { return "Base"; }
};
struct Derived : Base {
virtual std::string me() override { return "Derived"; }
};
void foo(std::shared_ptr<Base> ptr) {
using derived_raw_t = decltype(*ptr);
using derived_t = std::remove_reference<derived_raw_t>::type;
derived_t* x = new derived_t();
std::cout << x->me() << std::endl;
}
int main() {
std::shared_ptr<Base> ptr = std::make_shared<Base>(Derived());
foo(ptr);
}
答
你的目标不明确从你的问题。无论如何,decltype(e)
的行为如预期,因为它将返回编译时已知的“e
”的声明类型。
使用decltype
无法在运行时检索派生类的实际类型。如果要根据多态对象的运行时类型“克隆”,可以使用virtual
和override
。例如: -
struct Base {
// ...
virtual std::shared_ptr<Base> clone() {
return std::make_shared<Base>(*this);
}
};
struct Derived : Base {
// ...
virtual std::shared_ptr<Base> clone() {
return std::make_shared<Derived>(*this);
}
};
如果你想模仿协方差,请参阅:How To Make a clone method using shared_ptr and inheriting from enable_shared_from_this
'decltype'演绎静态(编译时)类型,这是'Base'在这种情况下。您可以将一个工厂虚拟函数添加到'Base'类中以生成该类的一个实例,并调用它来创建'x'调用'Derived'的工厂方法并创建一个Derived'类型的新实例。 – VTT
为什么你需要'foo'中的派生类型?你想达到什么目的? –
你不能通过'decltype'来做到这一点,因为这是一个编译时设施。最好的办法是在基类中重写的基类中提供一个'virtual'函数'create()'来创建相应类型的对象。通常,需要一个副本,相应的函数名称为clone()。 –