在C ++中的函数调用中声明静态变量

时间:2011-07-12 19:14:45

标签: c++

我有一个C ++程序,代码中有成千上万的字符串文字,需要翻译,例如:

statusBar->Print( "My Message" );

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

statusBar->Print( Translated( "My Message" ) );

问题是在分析后我发现在整个代码中查找是一个性能问题。我想做的是将这样的行换成:

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

但是由于代码中存在数千个这样的实例,它将容易出错(并且有点像维护噩梦)。我希望我可以将Translated变成一个宏,该宏声明了静态变量的内联。这显然不起作用。任何人都有更好的主意吗?

3 个答案:

答案 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;
}