我有一个C ++程序,代码中有成千上万的字符串文字,需要翻译,例如:
statusBar->Print( "My Message" );
我用一个函数包装了字符串文字,该函数在字典中查找值并返回翻译版本:
statusBar->Print( Translated( "My Message" ) );
问题是在分析后我发现在整个代码中查找是一个性能问题。我想做的是将这样的行换成:
static const char * translatedMessage5 = Translated( "My Message" );
statusBar->Print( translatedMessage5 );
但是由于代码中存在数千个这样的实例,它将容易出错(并且有点像维护噩梦)。我希望我可以将Translated
变成一个宏,该宏声明了静态变量的内联。这显然不起作用。任何人都有更好的主意吗?
答案 0 :(得分:3)
您可以更改为唯一的错误代码并将其编入索引吗?这简化了代码和查找,并且添加其他错误消息变得微不足道。此外,确保以这种方式添加的错误消息更加明显(例如,在此应用程序外部 - 可以轻松发布到“用户指南”或类似内容)。
#include <string>
#include <vector>
enum ErrorMessages
{
my_message,
my_other_message,
...
msg_high
};
std::vector<std::string> error_messages;
void init()
{
error_messages.resize(msg_high);
error_messages[my_msg] = "My Message";
error_messages[my_other_msg] = "My Other Message";
...
}
const char* const Translate(const ErrorMessage msg)
{
return error_messages[msg].c_str();
}
void f()
{
statusBar->Print(Translated(my_msg));
}
答案 1 :(得分:3)
打印消息所需的I / O时间应比任何字典查找时间多几个数量级。如果情况并非如此,那你就是做错了。
经过试验和测试的软件可以满足您的需求。我建议您研究GNU Gettext,这是其他所有FOSS项目使用的,或者只是在您的程序中使用它而不是自制解决方案。
编辑:使用C ++ 0x可以执行您想要的操作,但仍然可以考虑使用GNU Gettext作为真正的l10n引擎。这是一些概念验证的小代码:
#include <iostream>
const char* realTranslate(const char* txt)
{
std::cout << "*** translated " << txt << std::endl;
return txt; // use a real translation here such as gnu gettext
}
#define Translate(txt) \
(([]()->const char* \
{static const char* out = realTranslate(txt); return out;})())
int main ()
{
for (int i = 0; i < 10; ++i)
{
std::cout << Translate("This is a message") << std::endl;
std::cout << Translate("This is a message") << std::endl;
std::cout << Translate("This is another message") << std::endl;
}
}
我不确定真正的C ++标准将指定什么,但在gcc-4.6下,realTranslate()
函数被调用3次。
答案 2 :(得分:0)
这可能对你没有帮助,但你可以做的是声明一个std :: map,它将包含一个hash的地图 - &gt;文字对。这里的问题是,如果计算字符串上的哈希码与翻译它的工作量相同,我不知道。
char * Translate(char *source)
{
static std::map<int, char*> sources;
static std::map<int, char*> results;
int hashcode = CalculateHashCode(source);
std::map<int, char*>::const_iterator it = sources.find( source );
if ( it != sources.end() )
{
return results[ hashcode ];
}
... code to translate ...
results[ hashcode ] = translated;
}