繁体   English   中英

使用unique_ptr的工厂模式

[英]Factory pattern with unique_ptr

我有抽象类Agent,很少有派生类:Predator,Prey等。我想建立一个工厂,这给了我unique_ptr,我可以将其存储在基类的向量中。

问题是,当我有:

using creatorFunctionType = std::unique_ptr<Agent>(*)();

这部分还可以,但是在地图中,我不能将lambda用于:

return std::make_unique<Predator>();

但是当我尝试使用模板时:

template <class T>
using creatorFunctionType = std::unique_ptr<T>(*)();

其余功能无法编译。 我肯定在附近,我错过了一些有关模板的重要知识,但不知道该怎么做。 你能给我一些提示吗?

发布完整代码,可能会有所帮助

AgentFactory.h

#include "Interfaces/Agent.h"
#include "Enums.h"
#include <map>
#include <memory>

class AgentFactory
{
public:
    template <class T>
    using creatorFunctionType = std::unique_ptr<T>(*)();

    AgentFactory();
    std::unique_ptr<Agent> createAgent(Enums::AgentType agentType);
private:
    void registerAgentType(Enums::AgentType agentType, creatorFunctionType 
    creatorFunction);

    std::map<Enums::AgentType, creatorFunctionType> factoryRegister;
};

AgentFactory.cpp

#include "AgentFactory.h"
#include "Predator.h"
#include "Prey.h"

AgentFactory::AgentFactory()
{
    registerAgentType(Enums::AgentType::Predator, []() { return         
    std::make_unique<Predator>(); });
    registerAgentType(Enums::AgentType::Prey, []() { return     
    std::make_unique<Prey>(); });
}

std::unique_ptr<Agent> AgentFactory::createAgent(Enums::AgentType 
agentType)
{
    if (auto it = factoryRegister.find(agentType); it != 
    factoryRegister.end()) {
        return it->second();
    }

    return nullptr;
}

void AgentFactory::registerAgentType(Enums::AgentType agentType, 
creatorFunctionType creatorFunction)
{
    factoryRegister.insert(std::pair<Enums::AgentType, 
    creatorFunctionType>(agentType, creatorFunction));
}

编译错误:

1>d:\predator-prey\predator-prey\agentfactory.h(15): error C2955: 'AgentFactory::creatorFunctionType': use of alias template requires template argument list
1>d:\predator-prey\predator-prey\agentfactory.h(10): note: see declaration of 'AgentFactory::creatorFunctionType'
1>d:\predator-prey\predator-prey\agentfactory.h(17): error C3203: 'creatorFunctionType': unspecialized alias template can't be used as a template argument for template parameter '_Ty', expected a real type
1>d:\predator-prey\predator-prey\agentfactory.cpp(14): error C2064: term does not evaluate to a function taking 0 arguments
1>d:\predator-prey\predator-prey\agentfactory.cpp(22): error C3203: 'creatorFunctionType': unspecialized alias template can't be used as a template argument for template parameter '_Ty2', expected a real type
1>d:\predator-prey\predator-prey\agentfactory.cpp(22): fatal error C1903: unable to recover from previous error(s); stopping compilation

creatorFunctionType定义为

using creatorFunctionType = std::unique_ptr<Agent>(*)();

creatorFunctionType是指向函数的指针,该函数需要返回std::unique_ptr<Agent>函数。

但是,您的lambda没有显式的返回类型,因此编译器根据它们的return语句分别将其返回类型推导为std::unique_ptr<Predator>std::unique_ptr<Prey>

非捕获的lambda可隐式转换为函数指针,在这种情况下,这就是您想要的,但是lambda不会返回std::unique_ptr<Agent> ,因此无法将它们分配给creatorFunctionType 类型根本不匹配。

您需要明确关于lambda的返回类型,以便它们与creatorFunctionType期望的正确签名匹配,例如:

AgentFactory::AgentFactory()
{
    registerAgentType(Enums::AgentType::Predator,
        []() -> std::unique_ptr<Agent> { return std::make_unique<Predator>(); }
    );
    registerAgentType(Enums::AgentType::Prey,
        []() -> std::unique_ptr<Agent> { return std::make_unique<Prey>(); }
    );
}

使用上面的代码,lambdas现在将返回std::unique_ptr<Agent> ,满足creatorFunctionType期望。 并且return语句仍然按原样工作,因为只要U源自T ,就可以使用std::unique_ptr<U>初始化std::unique_ptr<T> ,这在您的情况下是正确的,因为PredatorPrey源自Agent

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM