错误:c++ [map]不是一个类型的名称。

13

我正在为一款文字冒险游戏编写文本命令解析器的一部分。

我正试图将用户输入的字符串与枚举类中的项目关联起来。以下内容位于我的头文件中:

#include <iostream>
#include <map>
#include <string>
using namespace std;

enum class Noun
{
    // Interrogation subjects
    name,                   // ask the subject his name
    base,                   // where is the base?
    attack,                 // when will the attack be?

    invalid
};

map < string, Noun > knownNouns;
knownNouns["name"]      = Noun::name;
knownNouns["base"]      = Noun::base;
knownNouns["attack"]    = Noun::attack;

Noun parseNoun(string &noun)
{
    auto n = knownNouns.find(noun);
    if ( n == knownNouns.end() ) {
        return Noun::invalid;
    }
    return n->second;

当我通过编译器运行这段代码时,我得到以下结果:

nouns.h:46:1: error: 'knownNouns' does not name a type
 knownNouns["name"]      = Noun::name;
 ^
nouns.h:47:1: error: 'knownNouns' does not name a type
 knownNouns["base"]      = Noun::base;
 ^
nouns.h:48:1: error: 'knownNouns' does not name a type
 knownNouns["attack"]    = Noun::attack;
 ^
nouns.h: In function 'Noun parseNoun(std::string&)':
nouns.h:52:10: error: 'n' does not name a type
     auto n = knownNouns.find(noun);
          ^
nouns.h:53:10: error: 'n' was not declared in this scope
     if ( n == knownNouns.end() ) {
          ^
nouns.h:54:16: error: 'Noun' is not a class or namespace
         return Noun::invalid;
                ^
nouns.h:56:12: error: 'n' was not declared in this scope
     return n->second;
            ^

这是我第一次尝试使用地图和枚举,我不确定我做错了什么。我也不是非常熟悉自动变量的使用,所以这在某种程度上是我习惯性编程的一个问题。我希望我能理解它的实现,一旦解决了我遇到的类型定义问题,错误就会消失。

编辑:真是尴尬。我复制粘贴了一个我已经更正过的错误。当代码无法编译时(即,当出现相同的问题时),情况仍然存在。

map < string, Noun > knownNouns;
knownNouns["name"]      = Verb::name;
knownNouns["base"]      = Verb::base;
knownNouns["attack"]    = Verb::attack;

被纠正为

map < string, Noun > knownNouns;
knownNouns["name"]      = Noun::name;
knownNouns["base"]      = Noun::base;
knownNouns["attack"]    = Noun::attack;

2
你必须将你的作业放在一个函数里面。 - Galik
我已经在一个c++11编译器中编译过了,是的。 - Bradley Evans
Galik,我正在寻找你所说的例子。你是否知道一个很好的构建它的方式的例子? - Bradley Evans
请参考@Oncaphillis的答案,了解我的意思。这些行必须在一个函数内部。 - Galik
2个回答

19

在命名空间范围内不能直接放置非声明结构。

C++翻译单元是一系列声明的序列。

类似赋值语句的非声明语句必须在函数体内。


修正后的代码:

#include <iostream>
#include <map>
#include <string>
using namespace std;

enum class Noun
{
    // Interrogation subjects
    name,                   // ask the subject his name
    base,                   // where is the base?
    attack,                 // when will the attack be?

    invalid
};

map< string, Noun > knownNouns = 
{
    { "name", Noun::name },
    { "base", Noun::base },
    { "attack", Noun::attack }
};

auto parseNoun( string const& noun )
    -> Noun
{
    // auto n = knownNouns.find(noun);
    // if ( n == knownNouns.end() ) {
        // return Noun::invalid;
    // }
    // return n->second;
    return Noun::invalid;
}

这里的knownNouns被初始化了。尽管=看起来很像是一条赋值语句,但实际上并不是。


你的转换为尾返回类型符号有什么原因吗? - Deduplicator
是的。如果我们不积极展示并使人们熟悉这种表示法,那么人们就不会如此迅速地采用它。 - Cheers and hth. - Alf
那是一个值得追求的目标,不过我个人会坚持只在它提供更具体好处的情况下使用它。 - Deduplicator
2
@BradleyEvans:按照编译器的建议添加选项“-std=c++11”(告诉它这是C++11代码)。您可能还想添加“-Wall”,“-Wextra”和“-pedantic-errors”。如果我没记错的话。;-)请注意,在此答案中,固定代码中没有名称“Verb”。因此,这不是您正在编译的代码。 - Cheers and hth. - Alf
1
这是对此的迟回复,但我注意到这个问题正在被浏览。我想澄清一下,当时这确实解决了我的问题。 - Bradley Evans
显示剩余5条评论

3

您不能像以下这样静态地初始化map条目:

 knownNouns["name"]      = Verb::name;
 knownNouns["base"]      = Verb::base;
 knownNouns["attack"]    = Verb::attack;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接