简体   繁体   English

std::map:模板 arguments 的编号错误,并分配了只读位置

[英]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.

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