[英]Factory pattern with unique_ptr
I have abstract class Agent, and few derived: Predator, Prey etc. I would like to make a factory, that gives me unique_ptr which I can store in vector of base class. 我有抽象类Agent,很少有派生类:Predator,Prey等。我想建立一个工厂,这给了我unique_ptr,我可以将其存储在基类的向量中。
Problem is, when I have: 问题是,当我有:
using creatorFunctionType = std::unique_ptr<Agent>(*)();
this part is ok, but in map I cannot use lambda with: 这部分还可以,但是在地图中,我不能将lambda用于:
return std::make_unique<Predator>();
But when I am trying to use template: 但是当我尝试使用模板时:
template <class T>
using creatorFunctionType = std::unique_ptr<T>(*)();
The rest of functions doesn't compile. 其余功能无法编译。 I am nearby sure, I missed something important about templates, but no idea what.
我肯定在附近,我错过了一些有关模板的重要知识,但不知道该怎么做。 Can you give me some hints?
你能给我一些提示吗?
Posting full code, may be helpful 发布完整代码,可能会有所帮助
AgentFactory.h 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 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));
}
Compilation errors: 编译错误:
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
When creatorFunctionType
is defined as 当
creatorFunctionType
定义为
using creatorFunctionType = std::unique_ptr<Agent>(*)();
creatorFunctionType
is a pointer-to-function that expects functions which return a std::unique_ptr<Agent>
. creatorFunctionType
是指向函数的指针,该函数需要返回std::unique_ptr<Agent>
函数。
However, your lambdas do not have explicit return types, so the compiler deduces their return types as std::unique_ptr<Predator>
and std::unique_ptr<Prey>
, respectively, based on their return
statements. 但是,您的lambda没有显式的返回类型,因此编译器根据它们的
return
语句分别将其返回类型推导为std::unique_ptr<Predator>
和std::unique_ptr<Prey>
。
A non-capturing lambda is implicitly convertible to a pointer-to-function, which is what you want in this case, however your lambdas do not return std::unique_ptr<Agent>
, so they cannot be assigned to creatorFunctionType
. 非捕获的lambda可隐式转换为函数指针,在这种情况下,这就是您想要的,但是lambda不会返回
std::unique_ptr<Agent>
,因此无法将它们分配给creatorFunctionType
。 The types simply do not match. 类型根本不匹配。
You need to be explicit about the return type of your lambdas so they match the correct signature that creatorFunctionType
is expecting, eg: 您需要明确关于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>(); }
);
}
With the above code, the lambdas will now return std::unique_ptr<Agent>
, satisfying what creatorFunctionType
expects. 使用上面的代码,lambdas现在将返回
std::unique_ptr<Agent>
,满足creatorFunctionType
期望。 And the return
statements still work as-is because std::unique_ptr<T>
can be initialized with a std::unique_ptr<U>
as long as U
derives from T
, which is true in your case since Predator
and Prey
derive from Agent
. 并且
return
语句仍然按原样工作,因为只要U
源自T
,就可以使用std::unique_ptr<U>
初始化std::unique_ptr<T>
,这在您的情况下是正确的,因为Predator
和Prey
源自Agent
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.