STD ::设置带有字符串键和潜在效率损失



让我们假设我有一个最直接的std::set

std::set<std::string> my_set;

现在,我有一个接受 const char*的函数,需要告诉我该字符串是否存在于集合中,以最直接的方式实现:

bool exists(const char* str) {
    return my_set.count(str) > 0;
}

现在,这是显而易见的效率损失。(潜在的(动态内存分配,然后出于无缘无故发生DealLocation。

我们如何消除它?我想比较我想用char*成为关键类型的std::string。一种方法是使用unique_ptr<char>而不是使用自定义比较器的密钥类型,但这会很尴尬。

问题实际上可以有效地将其推广到更广泛的情况:"如何调用与提供的类型相比而不转换为密钥类型的类型?"

P.S。我已经看到std :: string是map.find((的地图密钥和效率,但是我对答案不满意,这实际上不需要这种优化,虽然这显然是错误的。

您是正确的,默认情况下,count将将str转换为std::string可能会导致动态内存分配,并且至少进行不必要的副本。幸运的是C 14以

的形式为count添加过载
template< class K > 
size_type count( const K& x ) const;

将采用任何类型。要获得此过载,尽管您需要具有一个比较器来定义具有名称is_transparent的成员类型(该类型无关紧要,仅此而已(。尽管我们可以使用C 14中也引入的新std::less<void>,而不必编写一个。通过提供模板的operator(),这可以作为透明的比较器。这意味着您只需要更改

std::set<std::string> my_set;

to

std::set<std::string, std::less<>> my_set;
// or
std::set<std::string, std::less<void>> my_set;

然后该集合将使用bool operator<(std::string, const char*)进行比较,并且不需要临时或复制。

最新更新