字符串到字符串转换的flyweights:更好的性能选项

时间:2012-03-26 02:01:10

标签: c++ boost stdstring flyweight-pattern

所以我有一个字符串类型的轻量级:

typedef boost::flyweight< std::string, boost::flyweights::intermodule_holder > SymbolName_t;

我希望将其中的一个实例推送到它们的向量中,但天真的方法不起作用:

void PushSome( std::vector < SymbolName_t >& list)
{
  std::string& str = getSomeStr();
  list.push_back( str ); // <--- won't compile
}

所以我添加了一个临时构造函数:

void PushSome( std::vector < SymbolName_t >& list)
{
  std::string& str = getSomeStr();
  list.push_back( SymbolName_t(str) ); // <--- compiles ok
}

我的问题是:考虑到语言的限制,这种方法是否最佳?通过提供静态转换运算符,以其他方式实现此功能会带来哪些好处?我不认为通过非显式构造函数的隐式转换是有效选项,因为这需要修改boost::flyweight模板

2 个答案:

答案 0 :(得分:3)

如果您有C ++ 11编译器,则可以使用emplace_back而不是push_back,这样就无需复制。

答案 1 :(得分:1)

根据我对C ++的了解,您的上述代码可能是您的最佳选择,因为您传递了对列表的引用(未调用赋值或复制构造函数),获取对字符串的引用(同样,没有赋值或副本)构造函数),然后将新构造的SymbolName_t推送到列表中。不幸的是,STL containers operate on copies of their arguments,所以复制构造函数或赋值运算符(我不记得std::list在这里使用哪一个)将在那时被调用。其他选项可能包括转换运算符,但列表仍然必须构造初始对象,然后将其复制到STL容器。即使使用不同的STL容器,这仍然是正确的。所以转换运营商不会真的给你买任何东西,恕我直言。

您的上述代码(“编译好”块)可能是您最好的选择。在STL容器的约束下,我想不出更有效的方法。您可以使用shared_ptrSymbolName_t来购买一些性能,但由于boost:flyweight已经应该优化,只要管理内存,我不知道你买多少钱,如果有很多重复的字符串。