我有一组std :: std ::对,第二对是一个字符串。我想检查一下是否存在一对。
std::set< std::pair<size_t, std::string> > set_; bool exists(size_t x, const std::string& s) { std::set< std::pair<size_t, std::string> >::iterator i = set_.find(std::make_pair(x, s)); // copy of s is constructed by make_pair! return i != set_.end(); }
我经常调用此函数(是的,非常经常),所以我想在不制作字符串的临时副本的情况下执行此检查。有没有办法做到这一点,就像我在这里一样简单和简洁,但是没有制作字符串的临时副本?使用STL或Boost容器的任何解决方案都会很好。
答案 0 :(得分:5)
使用指向字符串的指针并覆盖谓词less(参见std :: set的构造函数)
答案 1 :(得分:2)
分析是否真的显示字符串副本在这里是一个重要问题?
如果是这样,你能否改变存在函数,使它接受pair
而不是两个参数,并安排将字符串直接构造到对中而不是单独构造?
如果你不能这样做,你总是可以使用shared_ptr<std::string>
作为pair
的第二个元素,并编写一个比较函数来比较地址中的字符串而不是值字符串。
答案 2 :(得分:1)
你可以随时自己找。
static pair<size_t, std::string> helper(0,"");
typedef std::set< std::pair<size_t, std::string> >::iterator iterator_type;
helper.first = x;
for (iterator_type i = set_.lower_bound(helper); i != set_.end(); ++i) {
if (i->first != x)
return false;
if (i->second == s)
return true;
}
return false;
答案 3 :(得分:1)
不幸的是,如果不将key_type
更改为类似引用的内容,则无法在C ++标准库中执行此操作。还有其他容器库具有模板参数化查找功能,允许不同的查找类型和比较器(例如Boost.Intrusive)。除此之外,您可以希望优化器删除复制构造。 (基准!)
答案 4 :(得分:-1)
编写一个保存目标字符串引用的仿函数:
struct match_str : public std::unary_function<bool, std::string>
{
match_str(const std::string& s) : s_(s) {};
bool operator()(const std::pair<size_t, std::string>& rhs) const
{
return rhs.second == s_;
}
};
用法:
std::set< std::pair<size_t, std::string> >::iterator i = std::find_if( set_.begin(), set_.end(), match_str(s) );