我试图在头文件中定义一个嵌套的映射变量,以用于键值查找(或由于嵌套而进行键,键值查找)。
对于C ++刚起步很抱歉,更不用说C ++ 98了。 我有中级JavaScript经验,可能会解释困难/习惯。
我正在尝试使用嵌套地图将口语翻译插入UI,
phrases["english"]["hello"] = "hi";
phrases["spanish"]["hello"] = "hola";
这将允许我使用短语[selectedLanguage] [“ hello”],该短语将根据selectedLanguage设置的内容返回(?)“ hi”或“ hola”。
这是为了使用户可以在多种语言之间切换,同时还允许我在需要时仅更改一个translations.h文件。
我有一个工作版本的代码,它将地图定义放在.cpp代码中,但我想创建类似头文件的内容,该文件定义了我的“短语”地图变量,以便我可以将语言翻译与.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()返回值的类型。我这样做不太舒服。
所以我已经将selectedLanguage定义为“ english”,因此我希望C ++将其作为newPhrases [“ english”]来处理,但是好像newPhrases并未定义,因为我期望它是从翻译导入后的语言。 h
我希望使这种代码能够正常工作,但是我也很欣赏为什么这是错误的处理方法的原因。预先感谢!
答案 0 :(得分:0)
让我们逐步尝试一下:
这是一个非常勇敢的任务:) 我猜你选择了那条艰难的道路。相反,这本来会更容易。好吧...就是这样。让我说:C ++与JavaScript有很大的不同。我强烈建议您进行无数的教程之一和/或读一本有关它的好书。有很多!
通常来说,头文件中应该从不定义,只有声明。如果您想进一步了解这一点,请google is your friend。
可以要做的是在头文件中有一个声明(使用关键字extern
或将其放入一个类中)和一个“定义” 。然后,链接器将找到该定义并将输出链接在一起。
我强烈建议您熟悉OO concept。从长远来看,它可能会为您提供帮助,并且可能会为您的问题提供更优雅的解决方案,但是在这里我不会详细介绍,请参阅其他标题。
这可行,但是我认为这是一种不好的做法,因为它在每次初始化屏幕时都会创建此对象,并且出于我不熟悉的原因。但我想将短语映射放入头文件中。
问题在于此对象(现在拥有)位于堆栈上,并且在离开该函数时将很快销毁(覆盖)。因此,如果您想从其他函数访问phrases
,它将无法正常工作。您可以在here中了解有关对象生存期the first link that popped up in google的更多信息,以及有关 scope 与 lifetime 的连接方式的更多信息。
这给了我错误:
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; }
最佳实践是不在头文件中实现您的功能,而仅在其中声明它们并在cpp文件中实现它们。对于
main()
,您不需要声明。只需使用cpp文件即可。
另一件事是,您正在newPhrases
的堆栈上创建main()
,因此newPhrases
也仅在main()
运行时有效。可能不是您想要的。
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 extern newPhrases
只是一个声明。它告诉编译器,有一个名为newPhrases
的东西某处(但不是在这里),它的类型为int
。实际上,您可能想告诉编译器该事物的类型为map<string, map<string, string> >
。此外,extern
声明不应位于函数内部。错误本身来自您的extern
声明。编译器认为newPhrases
的类型为int
,但是类型int
的对象没有方括号运算符(operator[]
)。但是,即使您修复了它无法运行的问题,所以我也不会详细介绍如何使某些事情可行。 (请参阅下一节中的一些建议和链接)
关于抽象语言并将其与代码分离的想法是好的。现在的问题是如何解决它。通常,编程中的一个中心习语是"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