[英]std::map: wrong number of template arguments, and assignment of read-only location
I am learning design patterns in C++.我正在学习 C++ 中的设计模式。 Now I am trying to implement Abstract Factory pattern.现在我正在尝试实现抽象工厂模式。 I have the following error related with std::map
.我有以下与std::map
相关的错误。 I want to have a map with FactoryType
as a key and unique_ptr
to this factory type as a value.我想要一个FactoryType
作为键和该工厂类型的unique_ptr
作为值。 Currently I am facing multiple issues which origin I don't understand.目前我面临着多个我不明白起源的问题。 Could you explain me what is wrong?你能解释一下有什么问题吗?
inc/GameObject/GameObjectFactory.hpp:13:59: error: wrong number of template arguments (1, should be at least 2)
std::unique_ptr<AbstractGameObjectFactory>> FactoriesArray;
^~
/usr/include/c++/8/bits/stl_map.h:100:11: note: provided for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’
class map
^~~
inc/GameObject/GameObjectFactory.hpp: In constructor ‘GameObjectFactory::GameObjectFactory()’:
inc/GameObject/GameObjectFactory.hpp:25:67: error: assignment of read-only location ‘"Player"[((GameObjectFactory*)this)->GameObjectFactory::m_factories]’
m_factories["Player"] = std::make_unique<PlayerObjectFactory>();
^
inc/GameObject/GameObjectFactory.hpp: In member function ‘std::unique_ptr<GameObject> GameObjectFactory::create(std::__cxx11::string)’:
inc/GameObject/GameObjectFactory.hpp:30:27: error: no match for ‘operator[]’ (operand types are ‘FactoriesArray’ {aka ‘int’} and ‘const string’ {aka ‘const std::__cxx11::basic_string<char>’})
auto obj = m_factories[type]->create();
Below is the code causing the issue:以下是导致问题的代码:
#include <map>
#include <memory>
#include <string>
#include "GameObject/AbstractGameObjectFactory.hpp"
#include "GameObject/PlayerObjectFactory.hpp"
typedef std::map<std::string type,
std::unique_ptr<AbstractGameObjectFactory>> FactoriesArray;
class GameObjectFactory
{
private:
FactoriesArray m_factories;
protected:
public:
GameObjectFactory()
{
m_factories["Player"] = std::make_unique<PlayerObjectFactory>();
}
std::unique_ptr<GameObject> create(const std::string type)
{
auto obj = m_factories[type]->create();
return std::move(obj);
}
};
Your typedef
is slightly malformed.您的typedef
格式略有错误。 You need to remove type
from std::string type
, like this:您需要从std::string type
中删除type
,如下所示:
typedef std::map<std::string,
std::unique_ptr<AbstractGameObjectFactory>> FactoriesArray;
Alternatively, you can use a type alias instead of a typedef
:或者,您可以使用类型别名而不是typedef
:
using FactoriesArray = std::map<std::string,
std::unique_ptr<AbstractGameObjectFactory>>;
On a separate note, you don't need the obj
variable in your create()
method:另外,您的create()
方法中不需要obj
变量:
std::unique_ptr<GameObject> create(const std::string type)
{
return m_factories[type]->create();
}
But, as @Jarod42 mentioned in comments, this can be risky, because if the requested type
is not in the map
then m_factories[type]
will return a new std::unique_ptr
that is holding a nullptr
, thus calling ->create()
will have undefined behavior .但是,正如@Jarod42 在评论中提到的那样,这可能是有风险的,因为如果请求的type
不在map
中,那么m_factories[type]
将返回一个持有nullptr
的新std::unique_ptr
,因此调用->create()
将有未定义的行为。 You need to validate that the type
exists, eg:您需要验证该type
是否存在,例如:
std::unique_ptr<GameObject> create(const std::string type)
{
auto iter = m_factories.find(type);
if (iter != m_factories.end())
return iter->create();
return nullptr; // or throw something...
}
Or:或者:
std::unique_ptr<GameObject> create(const std::string type)
{
return m_factories.at(type)->create();
}
std::map::at()
will throw a std::out_of_range
exception if the requested type
is not found.如果未找到请求的type
std::map::at()
将抛出std::out_of_range
::out_of_range 异常。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.