是否可以在编译时/运行时生成标记字符串的全局列表? [英] Is it possible to generate a global list of marked strings at compile time/runtime?
问题描述
因此,我正在努力将C ++应用程序翻译成多种语言.我当前正在使用的是类似的东西:
So, I'm working on translating my C++ app into multiple languages. What I'm currently using is something like:
#define TR(x) (lookupTranslatedString( currentLocale(), x ))
wcout << TR(L"This phrase is in English") << endl;
翻译来自CSV文件,该文件将英语字符串映射到翻译后的字符串.
The translations are from a CSV file which maps the english string to the translated string.
"This phrase is in English","Nasa Tagalog itong pagsabi"
这是简化的,但这是基本思想.
This is simplified, but that's the basic idea.
我的问题是关于生成需要翻译的英语短语列表.我只需要带有所有英语短语和空白翻译短语的CSV文件.我希望有可能在编译时或在运行时生成此列表.在编译时,我在想这样的事情:
My question is about generating the list of English phrases that need to be translated. I just need the CSV with all the english phrases, and blank translated phrases. I was hoping that it might be possible to either generate this list at compile time or at runtime. At compiletime I was thinking something like this:
#define TR(x) \
#warning x \
(lookupTranslatedString( currentLocale(), x ))
,然后解析编译日志或其他内容.这似乎效果不佳.
and then maybe parse the compile log, or something. This seems not to work so well.
在运行时也很棒.我正在考虑只是启动该应用程序,并拥有一个隐藏的命令,该命令将转储英文CSV.我已经看到了用于使用全局变量向中央列表注册命令的类似方法.它可能看起来像这样:
At runtime would also be great. I was thinking of just starting the app and having a hidden command that would dump the english CSV. I've seen similar methods used to register commands with a central list, using global variables. It might look something like this:
class TrString
{
public:
static std::set< std::wstring > sEnglishPhrases;
TrString( std::wstring english_phrase ) { sEnglishPhrases.insert( english_phrase ); }
};
#define TR(x) do {static TrString trstr(x);} while( false ); (lookupTranslatedString( currentLocale(), x ));
我知道上面的代码有两个问题.我怀疑它会编译,但是更重要的是,为了生成所有英语短语的列表,在访问sEnglishPhrases之前,我需要点击每个代码路径.
I know there's two problems with the above code. I doubt it compiles, but more importantly, in order to generate a list of all english phrases, I'd need to hit every single code path before accessing sEnglishPhrases.
看来我最终会写一个小解析器来阅读我所有的代码并寻找TR字符串,这实际上并不那么困难.我只是希望对C ++有所了解,如果有更好的方法可以做到这一点.
It looks like I'll end up writing a small parser to read through all my code and look for TR strings, which isn't really that tough. I was just hoping to learn a little more about C++, and if there's a better way to do this.
推荐答案
我认为您快到了.采取最后一个想法:
I think you're almost there. Taking the last idea:
class TrString
{
public:
static std::set< std::string > sEnglishPhrases;
std::string phrase;
TrString(const std::string& english_phrase ):phrase(english_phrase)
{ sEnglishPhrases.insert( english_phrase ); }
friend ostream &operator<<(ostream &stream, const TrString& o);
};
ostream &operator<<(ostream &stream, const TrString& o)
{
stream << lookupTranslatedString( currentLocale(), o.phrase);
return stream;
}
#define TR(x) ( TrString(x) )
// ...
std::cout << TR("This phrase is in English") << std::endl;
正如您所说,您确实需要在每个TR()
语句上运行代码,但是您可以配置一个单元测试框架来做到这一点.
And as you say, you do need to run the code over every TR()
statement, but you could configure a unit test framework to do this.
我的替代方法是使用上面的TrString类为每个模块创建静态变量:
My alternative would be to use the above TrString class to make static variables for each module:
// unnamed namespace gives static instances
namespace
{
TrString InEnglish("This phrase is in English");
// ...
}
现在,您只需要链接其他的main()
即可打印出TrString :: sEnglishPhrases
Now you just need to link in an alternative main()
to print out TrString:: sEnglishPhrases
这篇关于是否可以在编译时/运行时生成标记字符串的全局列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!