避免使用临时std::string来调用boost::unordereded_map::find
avoid temporary std::string to invoke boost::unordered_map::find
我有以下类型:
boost::unordered_map< std::string , Domain::SomeObject > objectContainer;
其只是使用std::strings
作为密钥的到某个域对象的映射。现在,可以构造std::string
,并将其与const char*
进行比较。(不需要显式std::string
临时,尽管可能正在发生隐式转换?)
当我尝试做类似的事情时,就会出现问题
void findStuff(const char* key) {
auto it = objectContainer.find(key); //<---build error
}
我在这里主要担心的是,仅仅为了与不可变的std::string
进行比较而构建std::string
似乎有点过头了,因为std::string
临时需要有自己的缓冲区,复制其中的const char*
内容,然后使用它来运行find()
方法。
有没有一个快捷方式可以避免在这里创建std::string
临时?
当然。像这样重新声明你的函数:
void findStuff(std::string const & key);
现在,从一开始就在调用代码中使用std::string
。
主要问题是容器的声明。
boost::unordered_map< std::string , Domain::SomeObject > objectContainer;
如果查看来源,我们将看到:
template<typename Key, typename Mapped, ...>
class unordered_map;
iterator find(const Key &);
因此,您有很强的接口限制。方法find始终使用Key类型作为参数,如果不更改容器密钥类型,则无法对其进行更改。
如果您确定在初始化std::string时损失了太多时间,则可以使用缓冲区(如果没有线程)。例如:
class objectContainer : public boost::unordered_map<std::string, SomeObject>
{
std::string _buffer;
public:
typedef boost::unordered_map<std::string, SomeObject> inherited;
objectContainer() { _buffer.reserve(1024); }
typename inherited::iterator find(const char * key)
{
_buffer = key;
return inherited::find(_buffer);
}
};
现在,缓冲区在构造函数中只分配一次内存,而不是每次调用find时都分配。
换句话说,使用您自己的密钥类型,它可以使用std::string和const char*,但在这种情况下,您应该用您的密钥类型定义Hash(boost::hash<Key>
)、谓词(std::equal_to<Key>
)的实现。
类似这样的东西:
class Key
{
public:
virtual ~Key();
virtual const char * key() = 0; // for hash and predicate
};
// predicate
struct equal_to_Key : binary_function <Key,Key,bool> {
bool operator() (const Key & x, const Key & y) const
{
return false; // TODO : compare Key here
}
};
class CharKey : public Key
{
const char * _key;
public:
virtual const char * key() { return _key; }
};
class StringKey : public Key
{
std::string _key;
public:
virtual const char * key() { return _key.c_str(); }
};
现在,您有一种方法可以获得const-char*并将其用于哈希和谓词。插入字符串时,您更喜欢使用StringKey。找到时-CharKey。
boost::unordered_map< Key , Domain::SomeObject, KeyHashFunctor, equal_to_Key > objectContainer;
void findStuff(const char* key) {
auto it = objectContainer.find(CharKey(key));
}
但是,在这种情况下,添加虚拟函数和创建Key对象可能会降低性能,使用objectContainer变得不舒服。
如果您真的不想创建任何额外的std::字符串,您可以逐个运行所有键,并将它们与旧的strcmp进行比较。但在我看来,Kerrek解决方案是最好的
您可以继承boost::unordered_map,并添加一个find,该find的版本为"char*",用于处理临时std::字符串。
//boost::unordered_map< std::string , Domain::SomeObject > objectContainer;
class ObjectContainer::public boost::unordered_map< std::string , Domain::SomeObject >
{
public:
iterator find(const char *key){const std::string constKey(key); return boost::unordered_map< std::string , Domain::SomeObject >::find(constKey);}
const_iterator find(const char *key)const {const std::string constKey(key); return boost::unordered_map< std::string , Domain::SomeObject >::find(constKey);}
};
ObjectContainer objectContainer;
也要对以上内容持保留态度,因为我还没有测试过。我目前的设置VS2008与boost 1.40没有问题,馈送一个const char*查找(我也没有使用auto)。它确实存在const char*和operator[]函数的问题,我已经为允许访问的operator[]功能做了类似的事情,如objectContainer["key"]
//<---生成错误
什么错误?它应该按原样编译。不幸的是,没有简单的方法可以做你想做的事。我也遇到过同样的问题(
存在多个问题:find()
的参数类型,std::equal_to
、std::hash
和std::less
的类型
尝试使用这个:-
void findStuff(const char* key)
{
std::string abc = (std::string)key; //<---build error
auto it = objectContainer.find(abc); // Now use "abc to find in Map
}
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- boost odeint什么时候真正调用观测者
- boost::bind()类似的东西,但用于函数调用
- 赋值 boost::intrusive_ptr 而不调用构造函数?
- Boost Beast 异步服务器失败,断言失败:(id_ != T::id) 在多个 aync 调用中
- Boost Json 写入错误:调用 'boost::p roperty_tree::basic_ptree<std::__cxx11
- 调用boost v1.58中的函数时出现模板名称使用无效错误
- 调用boost.asio的异步函数时,线程是什么时候创建的
- 使用单独的参数调用"boost::process::system()"时,获取"execv
- 与 boost odeint 集成期间的析构函数调用
- C++11 - 获取编译时的所有类变量,并在没有 Boost 的情况下为它们调用方法
- 为什么使用线程池时嵌套调用 boost::async 会阻塞?
- 编译在 Python 代码内部调用的 C++ 代码时出错,使用 Boost Python
- 错误:对'boost::.......'的调用不匹配
- 使用 boost::thread 运行函子,但析构函数被错误地调用
- Boost 协程由于对 callcc 的不明确调用而无法编译
- 保持 boost.process 在函数之外处于活动状态,该函数被调用
- 最佳实践:我应该使用 std::thread、boost 还是本机调用
- Boost::调用join时发生线程访问冲突
- backtrace-隐藏标准库和boost调用