在C++; 我有一个C++程序,代码中有成千上万个字符串文字,需要翻译,例如: statusBar->Print( "My Message" );

在C++; 我有一个C++程序,代码中有成千上万个字符串文字,需要翻译,例如: statusBar->Print( "My Message" );,c++,C++,我使用一个函数包装字符串文本,该函数在字典中查找值并返回翻译版本: statusBar->Print( Translated( "My Message" ) ); 问题是,在分析之后,我发现在整个代码中进行这种查找是一个性能问题。我想做的是将这样的行更改为: static const char * translatedMessage5 = Translated( "My Message" ); statusBar->Print( translatedMessage5 ); 但是由

我使用一个函数包装字符串文本,该函数在字典中查找值并返回翻译版本:

statusBar->Print( Translated( "My Message" ) );
问题是,在分析之后,我发现在整个代码中进行这种查找是一个性能问题。我想做的是将这样的行更改为:

static const char * translatedMessage5 = Translated( "My Message" );
statusBar->Print( translatedMessage5 );

但是由于代码中有数千个这样的实例,它很容易出错(并且有点像维护噩梦)。我希望我能把
翻译成一个宏,它可以在线声明静态变量。这显然行不通。有谁有更好的主意吗?

您能转换为唯一的错误代码并将其索引到向量中吗?这简化了代码和查找,添加额外的错误消息变得微不足道。此外,还可以确保以这种方式添加的错误消息更加可见(例如,在该应用程序外部,可以轻松地发布到“用户指南”或类似文件中)

#包括
#包括
枚举错误消息
{
我的留言,
我的另一条信息,
...
味精高
};    
std::向量错误消息;
void init()
{
错误消息。调整大小(消息高);
错误消息[我的消息]=“我的消息”;
错误消息[我的其他消息]=“我的其他消息”;
...
}
常量字符*常量翻译(常量错误消息消息消息)
{
返回错误消息[msg].c_str();
}
void f()
{
状态栏->打印(翻译为my_msg);
}

这可能对您没有帮助,但您可以做的是声明一个std::map,它将保存一个哈希->文本对的映射。这里的问题是,在字符串上计算哈希代码是否与翻译它的工作量相同,这我不知道

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;
}
char*翻译(char*源)
{
静态std::映射源;
静态std::映射结果;
int hashcode=CalculateHashCode(源代码);
std::map::const_迭代器it=sources.find(source);
if(it!=sources.end())
{
返回结果[哈希代码];
}
…要翻译的代码。。。
结果[哈希代码]=已翻译;
}

打印邮件所需的I/O时间应该比任何字典查找时间多几个数量级。如果不是这样,你就做错了

经过测试的软件可以满足您的需求。我建议你要么学习,这是每个其他自由和开放源码软件项目使用的,要么只是在你的程序中使用它,而不是自制的解决方案

<> > >编辑:用C++ 0x可以做你想做的,但是仍然要考虑使用你真正的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;
    }
}
#包括
const char*realTranslate(const char*txt)
{

std::cout
是如何翻译的
的?您使用的是高效的哈希表实现吗?@Brian-我不说这是一个解决方案,但您是如何实现字典的?它是否使用最合适的数据结构进行查找(例如boost::unorded_map),因为Translated()显然,需要一个字符串,即使是高效的哈希也必须对整个字符串进行哈希,这是非常昂贵的。是的,这是我尝试的第一件事。因为表的大小是固定的,所以我将其分配为一个带有键字符串、值字符串和“next”的单个大数组索引。然后是一个哈希数组,它指向每个哈希键的第一个索引。大部分时间都花在实际计算哈希键上。你的应用程序支持在运行时更改语言,还是在启动时固定?如果是前者,在第一次调用函数时缓存翻译后的字符串是一个非常糟糕的主意(tm)!
enum
值没有名称空间,您可能需要修复最后一行。@安德烈:它们在MSVC和C++0x中有效。这很可能是我必须要做的。我试图避免这样做,因为必须转换成千上万行已经存在的代码(不仅工作量很大,而且还容易出错)。此外,很难确定和删除未使用的消息。将其视为一种好处--您可以合理化所有现有错误消息,并将它们放在一个易于导出的位置。此外,如果需要进行“翻译”(如语言翻译支持),则,只需更改错误消息并保持其余代码原样就可以支持其他语言。@DeadMG:除非另有说明,否则我假设C++03。+1,如果OP希望自己的程序使用i18n,gettext是可以使用的工具。即使他想编写自己的解决方案,他也应该研究gettext手册,以在某些方面看到这一点cases(复数形式)仅仅做一个简单的字典查找是不够的。C++0x lambda版本非常棒。我还没有意识到这是可能的。FWIW真正的问题不是本地化,但我用它作为我的例子,因为它更容易摸索。
#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;
    }
}