C ++静态结构模板方法返回枚举类型

时间:2016-10-15 05:10:07

标签: c++ templates struct

我真的不懂c ++,但我现在已经搞乱了一段时间,虽然我知道我应该花时间去学习它。

无论如何,我在这里遇到的问题是静态结构,我不确定它的结构是否正确。

enum ItemTypes_t {  
    ITEM_TYPE_KEY,
    ITEM_TYPE_MAGICFIELD,
    ITEM_TYPE_DEPOT,
    ITEM_TYPE_REWARDCHEST,
    ITEM_TYPE_MAILBOX,
    ITEM_TYPE_TRASHHOLDER,
    ITEM_TYPE_TELEPORT,
    ITEM_TYPE_DOOR,
    ITEM_TYPE_BED,
    ITEM_TYPE_RUNE
};

template <typename T>
static struct tTypes {
public:
    const char* name;
    T value;
    T getEnums(std::string itemName);
};

tTypes<ItemTypes_t>itemEnum[] = {
    { "key", ITEM_TYPE_KEY },
    { "magicfield", ITEM_TYPE_MAGICFIELD },
    { "depot", ITEM_TYPE_DEPOT },
    { "rewardchest", ITEM_TYPE_REWARDCHEST },
    { "mailbox", ITEM_TYPE_MAILBOX },
    { "trashholder", ITEM_TYPE_TRASHHOLDER },
    { "teleport", ITEM_TYPE_TELEPORT },
    { "door", ITEM_TYPE_DOOR },
    { "bed", ITEM_TYPE_BED },
    { "rune", ITEM_TYPE_RUNE }
};

ItemTypes_t tTypes<ItemTypes_t>::getEnums(std::string itemName) {
    for (int i = 0; itemEnum[i].name; i++) {
        if (itemEnum[i].name == find) {
            return itemEnum[i].value;
        }
    }
    return;
};

我像这样创建它的实例。

tTypes<ItemTypes_t> itemType = tTypes<ItemTypes_t>();

然后这样称呼它。

ItemTypes_t storage;

storage = itemType.getEnums("some item name is passed here as a string");

没有错误,但我真的不了解结构,或者甚至不知道它是否会起作用。

编辑:这是一些错误

error C2988: unrecognizable template declaration/definition
error C2059: syntax error: '<end Parse>'
error C2977: 'tTypes': too many template arguments
note: see declaration of 'tTypes'
error C2977: 'tTypes': too many template arguments
note: see declaration of 'tTypes'
error C2027: use of undefined type 'tTypes'
note: see declaration of 'tTypes'
error C2027: use of undefined type 'tTypes'
note: see declaration of 'tTypes'
error C2027: use of undefined type 'tTypes'
note: see declaration of 'tTypes'
error C2561: 'getEnums': function must return a value
note: see declaration of 'getEnums

我尝试使用地图但是没有用

std::map<std::string, ItemTypes_t> tTypes = {
    { "key", ITEM_TYPE_KEY },
    { "magicfield", ITEM_TYPE_MAGICFIELD },
    { "depot", ITEM_TYPE_DEPOT },
    { "rewardchest", ITEM_TYPE_REWARDCHEST },
    { "mailbox", ITEM_TYPE_MAILBOX },
    { "trashholder", ITEM_TYPE_TRASHHOLDER },
    { "teleport", ITEM_TYPE_TELEPORT },
    { "door", ITEM_TYPE_DOOR },
    { "bed", ITEM_TYPE_BED },
    { "rune", ITEM_TYPE_RUNE },
};

编辑2:

我在线使用c ++编译器来测试我认为它应该如何工作并且工作正常(地图)但是当我在项目中尝试它时它根本不起作用。

这只是一个非常基本的例子。

#include <iostream>
#include <map>

using namespace std;

enum a : unsigned int {
    RED = 23, BLACK = 43, BLUE = 56
};

map<string, a> colors = {
    {"black", BLACK},
    {"green", RED},
    {"yellow", BLUE}
};

int main()
{
   cout << "test map " << colors["green"] << endl; 

   return 0;
}

这是结果

sh-4.3$ g++ -std=c++11 -o main *.cpp                                                                                                                                
sh-4.3$ main                                                                                                                                                        
test map 23 

感谢大家的建议,问题不在于地图或地图是否有效..我试图用静态结构模板构建的怪物显然是错误的。

这里真正的问题是从哪里读取字符串。

我只是解释一下,通常这个数据是从xml文件中读取的,但是我构造了一些代码来从xml文件的解析生成一个lua表,这样我就可以重新编写函数来加载lua有嵌套错误问题的表所以这就是我使用地图的原因,实际上有几个。

我已经工作了好几个小时了,所以很自然地看一下,代码中的字符串不是问题也不是地图,它的lua文件,它的一些属性是不同的字符情况..所以,当我扫描地图的索引时,即使是相同的拼写单词也是如此,这是一个不同的字符大小写。

解决方案:

在构建lua表时,最简单的解决方案是让我小写属性。

结论:

有效,而不是字面上50k未读的属性现在我只有20或30个未读属性..感谢大家的帮助,我绝对会查看这些书!

2 个答案:

答案 0 :(得分:1)

您可以像这样定义getEnums函数:

ItemTypes_t tTypes<ItemTypes_t>::getEnums(std::string itemName) { ... }

然而,这不是如何定义模板化类的成员函数。这是一个专业化,你不能专门化模板结构的单个成员,你必须专门化整个结构。

你应该改为

template<typename T>
T tTypes<T>::getEnums(std::string itemName) { ... }

您还应该注意其他一些事项。就像字符串和枚举值之间的映射一样,它应该作为构造函数的参数传递给tTypes类,并存储在类内部。

答案 1 :(得分:0)

您的代码可以使用std :: map并使用单例类实现,如下所示:

#include <map>
#include <string>

enum class repo_t {ITEM_TYPE_MAGICFIELD,ITEM_TYPE_DEPOT}; //etc

class repo
{
   private:
     std::map<std::string,repo_t> items;
     repo()
     {
     items.insert(std::make_pair("magicfield", repo_t::ITEM_TYPE_MAGICFIELD));
     items.insert(std::make_pair("depot", repo_t::ITEM_TYPE_DEPOT ));
     items.insert(std::make_pair("rewardchest",repo_t::ITEM_TYPE_REWARDCHEST ));
         //etc
      } 

   public:

   static repo*& get_instance()
    {
        static repo* obj(new repo());
        return obj;
    }

    ~repo(){}

    bool find(std::string key, repo_t& result)
    {
       auto it = items.find(key);
       if(it ==  items.end())
             return false;
       result = *it;
       return true;
    }


};

//usage

void main()
{
    repo_t result;
    bool found = repo::get_instance()->find("magicfield",result);
    if(found)
    {
       // do something with result
    }
    else
    {
      // key not found
    }


}