如何在头文件中定义嵌套映射以便在 .cpp 中使用

How to define a nested map in a header file for use in .cpp

我正在尝试在头文件中定义嵌套映射变量以用于键值查找(或键、键值查找,因为它是嵌套的)。

抱歉,您对 C++ 还是个新手,更不用说 C++98 了。 我有中级 JavaScript 经验,这可以解释 difficulties/habits。

我正在尝试使用嵌套映射将口语翻译插入 UI,其结构类似于:

phrases["english"]["hello"] = "hi";
phrases["spanish"]["hello"] = "hola";

这将允许我使用短语[selectedLanguage]["hello"],这将 return(?) "hi" 或 "hola" 取决于 selectedLanguage 的设置.

这样一来,用户可以在不同语言之间切换,同时还允许我只更改一个 translations.h 所需的文件 if/when。

我有一个代码的工作版本,它将地图定义放在 .cpp 代码中,但我想创建类似头文件的东西,它定义了我的 'phrases' 地图变量,以便我可以分开来自其余 .cpp 代码的语言翻译。

我当前的工作代码如下所示:

UI.cpp:

void CScnMgr::InitScreens(){

  // selectedLanguage is defined 
  string selectedLanguage = "spanish";

  //phrases map is defined
  map <string, map <string, string> > phrases;
  phrases["english"]["hello"] = "hi";
  phrases["spanish"]["hello"] = "hola";

  // then later when i need to use either translation...
  phrases[selectedLanguage]["hello"];
}

这行得通,但我认为这是一种不好的做法,因为每次初始化屏幕时它都会创建这个对象,而且出于我不熟悉的原因。但是我想把我的短语映射到一个头文件中。

这给我错误:

translations.h:

#include <string>
#include <map>

int main(){
  map <string, map <string, string> > newPhrases;
  map <string, string> spanish;
  map <string, string> english;

  spanish["hello"] = "hola";
  english["hello"] = "hi";

  newPhrases["spanish"] = spanish;
  newPhrases["english"] = english;
  return 0;
}

UI.cpp:

#include "translations.h"


void CScnMgr::InitScreens(){
  int extern newPhrases;

// further down where I need to display to the UI...
  newPhrases[selectedLanguage]["hi"]

}

错误:

UI.cpp: error: no match for 'operator[]' in 'newPhrases[selectedLanguage]'

我当然不明白为什么把 "int" 放在 'int extern newPhrases' 中通过编译,但这就是它在那里的原因,我给它的类型是 main() return。我觉得这样做不太舒服。

所以我将 selectedLanguage 定义为 "english" 所以我希望 C++ 将其处理为 newPhrases["english"],但似乎 newPhrases 没有像我期望的那样定义从 translations.h

导入后

我很希望有一种方法可以使这段代码正常工作,但我也很感激为什么这是错误的方法。提前致谢!

让我们一步步尝试:

JavaScript 到 C++

这是一项非常勇敢的任务:) 我猜你选择了这条艰难的道路。反过来会更容易。好吧……就是这样。我只想说:C++ 感觉和 JavaScript 很不一样。我强烈建议做无数教程之一 and/or 阅读一本关于它的好书。有很多!

文件结构

一般来说,永远不会在header文件中有定义,只有声明。如果你想了解更多,google is your friend.

可以做的是在header文件中有一个声明(使用关键字extern或者将其放入(单独的)cpp 文件中的 class) 和 definition 中。 linker 然后会找到该定义和 link 输出。

糟糕

我强烈建议您熟悉 OO concept。它可能会在很长一段时间内对你有所帮助运行,并且可能会有更优雅的解决方案来解决你的问题,但我不会在这里详细介绍,请参阅其他标题。

分析你当前的代码

  • This works, but I assume this is bad practice because it is creating this object every time the screens are initialized and for reasons I'm unfamiliar with. But I want to put my phrases map into a header file.

    问题是你现在拥有的这个 object 存在于堆栈中,当你离开函数时很快就会被销毁(覆盖)。所以如果你想从不同的函数访问 phrases 它将不起作用。您可以阅读更多关于 object 生命周期 here and a little more about how scope is connected to lifetime in the first link that popped up in google.

  • This is giving me errors:

    translations.h:

    #include <string>
    #include <map>
    
    int main(){
      map <string, map <string, string> > newPhrases;
      map <string, string> spanish;
      map <string, string> english;
    
      spanish["hello"] = "hola";
      english["hello"] = "hi";
    
      newPhrases["spanish"] = spanish;
      newPhrases["english"] = english;
      return 0;
    }
    

    Best practice is to not implement your functions in header files, but only declare them there and implement them in cpp files. For main(), you don't need a declaration. Just use a cpp file.

    另一件事是您在 main() 的堆栈上创建 newPhrases,因此 newPhrases 也仅在 main() 处于 运行ning 时存在.可能不是你想要的。

  • UI.cpp:

    #include "translations.h"
    
    void CScnMgr::InitScreens(){
      int extern newPhrases;
    
    // further down where I need to display to the UI...
      newPhrases[selectedLanguage]["hi"]
    
    }
    

    Errors:

    UI.cpp: error: no match for 'operator[]' in 'newPhrases[selectedLanguage]'
    

    int extern newPhrases 只是一个声明。它告诉编译器在某处(但不在这里)有一个名为 newPhrases 的东西,它的类型是 int。实际上你会想告诉编译器这个东西是 map<string, map<string, string> > 类型。此外,extern 声明不应该在函数内部。错误本身来自您的 extern 声明。编译器认为 newPhrasesint 类型,但是 int 类型的东西没有 square-bracket-operator (operator[])。但即使你修复了它也不会 运行,所以我不会详细介绍如何让某些东西可能工作。 (请参阅下一节中的一些建议和 links)

关于本地化/国际化/多语言支持的一般方法

想要抽象语言并将其从代码中分离出来的心态是好的。现在的问题是如何解决。一般编程中的中心习语是 "not to reinvent the wheel".

基本上,我认为你的问题与这个问题重复:
C++, Multilanguage/Localisation support

我发现的另一个非常相似的主题:
Bests practices for localized texts in C++ cross-platform applications?

还有一个:
How to support multiple language in a Linux C/C++ program?

如果你想坚持你的方法,看看这个(性能):
C++ map<std::string> vs map<char *> performance (I know, "again?")

在上面提到的帖子中,有很多建议,也有框架可以很好地解决你的问题。我还建议您自己进行研究,因为有些问题相当陈旧,而且可能已经有一些新问题了。就问 your loyal friend