std :: set <std :: pair <size_t,std :: string =“”>&gt; :: find(),没有字符串复制结构</std :: pair <size_t,>

时间:2011-01-10 16:15:17

标签: c++ stl

我有一组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容器的任何解决方案都会很好。

5 个答案:

答案 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) );