动态多态类型扣除使用decltype

问题描述:

你能给我一个提示,如何使这段代码工作,因为我想要它?我想derived_tDerived,但它总是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); 
} 
+1

'decltype'演绎静态(编译时)类型,这是'Base'在这种情况下。您可以将一个工厂虚拟函数添加到'Base'类中以生成该类的一个实例,并调用它来创建'x'调用'Derived'的工厂方法并创建一个Derived'类型的新实例。 – VTT

+0

为什么你需要'foo'中的派生类型?你想达到什么目的? –

+0

你不能通过'decltype'来做到这一点,因为这是一个编译时设施。最好的办法是在基类中重写的基类中提供一个'virtual'函数'create()'来创建相应类型的对象。通常,需要一个副本,相应的函数名称为clone()。 –

你的目标不明确从你的问题。无论如何,decltype(e)的行为如预期,因为它将返回编译时已知的“e”的声明类型。

使用decltype无法在运行时检索派生类的实际类型。如果要根据多态对象的运行时类型“克隆”,可以使用virtualoverride。例如: -

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

+0

目标是使派生类中的克隆函数能够返回指向派生的指针,而不是基指针。我可以用另一种方式知道我何时派生实例或基地?例如。 typeid()。name不知何故,但我不需要一个const char *类型,但类型本身 – banana36

+0

@ banana36:查看我最后发布的链接,并改善你的问题与真正的目标。 –

+0

是的,链接帮助。谢谢。 – banana36