所以我有一个字符串类型的轻量级:
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
模板
答案 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_ptr
到SymbolName_t
来购买一些性能,但由于boost:flyweight
已经应该优化,只要管理内存,我不知道你买多少钱,如果有很多重复的字符串。