我有以下类型:
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
临时?
答案 0 :(得分:2)
当然。像这样重新声明你的功能:
void findStuff(std::string const & key);
现在从一开始就在调用代码中使用std::string
。
答案 1 :(得分:0)
如果你真的不想创建任何额外的std :: string,你可以逐个遍历所有键,并将它们与旧的strcmp进行比较。但在我看来,Kerrek解决方案是最好的
答案 2 :(得分:0)
你可以继承boost :: unordered_map并添加一个带有“char *”版本的find,它可以为你处理temp std :: string。
//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与增强1.40没有问题,提供一个const char *来查找(我也没有使用auto)。它确实存在const char *和operator []函数的问题,我为operator []函数做了类似的事情,允许像objectContainer [“key”]
这样的访问答案 3 :(得分:0)
主要问题是声明您的容器。
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 *,但在这种情况下你应该定义哈希(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 *并在hash和谓词中使用它。插入字符串时,您更喜欢使用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变得不舒服。
答案 4 :(得分:0)
//&lt; ---构建错误
什么错误?它应该按原样编译。 不幸的是,没有简单的方法可以做你想做的事。我被同样的问题困扰了。 :(
存在多个问题:find()
的参数类型,std::equal_to
的类型,std::hash
和std::less
答案 5 :(得分:-2)
尝试使用: -
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
}