创建动态推导类型的智能指针?

Create a smart pointer of a dynamically deduced type?

提问人:Fzza 提问时间:10/26/2023 更新时间:10/26/2023 访问量:46

问:

是否可以在不使用 if 序列的情况下创建动态推断类型的指针?

我应该使用什么作为地图值类型?

class Vehicle {
  public:
    virtual void run() =0;
};

// Derived class
class Mustang: public Vehicle {
  public:
    string model = "Mustang";
    virtual void run() {std::cout<<model<<std::endl;};
};

// Derived class
class Ford: public Vehicle {
  public:
    string model = "Ford";
    virtual void run() {std::cout<<model<<std::endl;};
};

std::unordered_map<std::string, std::type_index> m {{"Mustang",typeid(Mustang)},{"Ford",typeid(Ford)} };

int main()
{
    std::unique_ptr<Vehicle> v;
    std::string s{"Mustang"};
    
    v=std::make_unique<m.at(s)>;
    v->run(); //what i want to achieve is print "Mustang"

    return 0;
}
C++ 模板 元编程 智能指针

评论

1赞 463035818_is_not_an_ai 10/26/2023
在将代码发布到此处之前,请不要从代码中删除 includes 和 using 声明。我花了更多的时间来添加它们,而不是添加缺少的内容以获得所需的输出;)
0赞 Sam Varshavchik 10/26/2023
模板参数在编译时必须已知,不能在运行时“动态推导”。这是 C++ 的基础,没有例外,C++ 不是这样工作的。

答:

2赞 463035818_is_not_an_ai 10/26/2023 #1

您可以在映射中存储返回 a 的可调用对象:std::unique_ptr<Vehicle>

#include <string>
#include <memory>
#include <iostream>
#include <unordered_map>
#include <functional>

class Vehicle {
  public:
    virtual void run() =0;
    virtual ~Vehicle() {}
};

// Derived class
class Mustang: public Vehicle {
  public:
    std::string model = "Mustang";
    virtual void run() {std::cout<<model<<std::endl;};
};

// Derived class
class Ford: public Vehicle {
  public:
    std::string model = "Ford";
    virtual void run() {std::cout<<model<<std::endl;};
};

std::unordered_map<std::string, std::function<std::unique_ptr<Vehicle>()>> m {
    {"Mustang",[]()->std::unique_ptr<Vehicle> { return std::make_unique<Mustang>();}},
    {"Ford",[]() ->std::unique_ptr<Vehicle> { return std::make_unique<Ford>();}} 
    };

int main()
{
    std::unique_ptr<Vehicle> v;
    std::string s{"Mustang"};
    
    v=m.at(s)();
           //^^---------- note the () to call the function 
           //             that returns the std::unique_ptr
    v->run(); // prints Mustang

    return 0;
}

现场演示


这:

[]()->std::unique_ptr<Vehicle> { return std::make_unique<Mustang>();}

相当冗长,因此您可能需要编写一个辅助函数:

template <typename T> 
std::unique_ptr<Vehicle> create_vehicle() {
       return std::make_unique<T>();
}

PS:您缺少虚拟析构函数。Vehicle