unique_ptr 的工厂模式
Factory pattern with unique_ptr
我有抽象的 class Agent,还有一些派生的:Predator、Prey 等。我想建一个工厂,它给了我 unique_ptr 我可以将其存储在基础向量中 class.
问题是,当我有:
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
是一个 pointer-to-function,它需要 return 一个 std::unique_ptr<Agent>
.
的函数
但是,您的 lambda 表达式没有明确的 return 类型,因此编译器根据它们的 return
语句。
A non-capturing lambda 可以隐式转换为 pointer-to-function,在这种情况下这是您想要的,但是您的 lambda 不 return std::unique_ptr<Agent>
,因此它们无法分配给 creatorFunctionType
。类型根本不匹配。
您需要明确说明您的 lambda 的 return 类型,以便它们匹配 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 现在将 return std::unique_ptr<Agent>
,满足 creatorFunctionType
的期望。 return
语句仍然有效 as-is 因为 std::unique_ptr<T>
可以用 std::unique_ptr<U>
初始化,只要 U
派生自 T
,这是真的在你的情况下,因为 Predator
和 Prey
来自 Agent
.
我有抽象的 class Agent,还有一些派生的:Predator、Prey 等。我想建一个工厂,它给了我 unique_ptr 我可以将其存储在基础向量中 class.
问题是,当我有:
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
是一个 pointer-to-function,它需要 return 一个 std::unique_ptr<Agent>
.
但是,您的 lambda 表达式没有明确的 return 类型,因此编译器根据它们的 return
语句。
A non-capturing lambda 可以隐式转换为 pointer-to-function,在这种情况下这是您想要的,但是您的 lambda 不 return std::unique_ptr<Agent>
,因此它们无法分配给 creatorFunctionType
。类型根本不匹配。
您需要明确说明您的 lambda 的 return 类型,以便它们匹配 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 现在将 return std::unique_ptr<Agent>
,满足 creatorFunctionType
的期望。 return
语句仍然有效 as-is 因为 std::unique_ptr<T>
可以用 std::unique_ptr<U>
初始化,只要 U
派生自 T
,这是真的在你的情况下,因为 Predator
和 Prey
来自 Agent
.