2011-01-10 56 views
3

我有std :: pair的std :: set,第二对是一个字符串。我想检查一组中是否存在一对。std :: set <std :: pair <size_t,std :: string>> :: find(),没有字符串拷贝构造

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

+1

你就错了。编写简单,干净并且可行的代码。然后顺便说下去,当你完成时,* profile *你的应用程序,并优化结果说慢;不是猜测。 – GManNickG 2011-01-10 17:03:50

+0

这里有很多的建议,我不应该担心这个函数的性能,除非我有证据表明这个函数导致性能问题,我只想提到读这篇文章的任何人,这是非常好的建议。只是不在这个特殊情况下。 – 2011-01-10 17:40:34

+1

复制一个字符串并不像您想象的那么昂贵。当你证明它是一个瓶颈点时,首先编写干净的代码优化后者。 – 2011-01-10 18:31:47

回答

5

使用指向字符串的指针,并重写谓语以下(见的std ::构造集)

+0

我认为这可能是最好的答案。我正在使用C++ 03(没有C++ 0x r值参考功能,所以不能使用unique_ptr),是的,我想保持O(log n)时间。这将是混乱的,但C++是凌乱的。 – 2011-01-10 16:45:47

+1

这有强迫您手动管理存储在容器中的内存的不良副作用。在原始代码中,当集合超出范围时,容器中保存的内存将自动被容器释放,通过将其更改为保持指针,集合析构函数不会释放字符串。这会增加代码的其他部分的复杂性和脆弱性。 – 2011-01-10 16:55:02

2

难道分析实际上显示的字符串拷贝是显著问题就在这里?

如果是这样,你是否能够改变存在函数,因此它接受pair而不是两个参数,并安排将字符串直接构建到对而不是分别?

如果你不能这样做,你总是可以使用shared_ptr<std::string>作为你的pair的第二个元素,并且调整一个比较函数来比较来自地址而不是值字符串的字符串。

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; 
1

不幸的是,你不能这样做,在C++标准库不改变key_type的东西参考等。还有其他容器库具有模板参数化查找功能,该功能允许不同的查找类型和比较器(例如Boost.Intrusive)。除此之外,您可以希望优化器删除复制构造。 (!基准)

-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)); 
相关问题