【发布时间】:2017-05-13 12:21:31
【问题描述】:
我有一个带有shared_ptr<T> 键的std::map,我需要它使用实际值(类型为T,即*key)进行查找,而不是共享指针本身。
我知道我可以编写自己的自定义比较器(如下所示),但我想知道 STL 是否专门为此目的提供了比较器。
为了演示我在说什么,我创建了这个简单的例子,它使用了std::set 字符串(我也把它放在了on GitHub as a gist):
#include <set>
#include <string>
#include <memory>
#include <iostream>
#include <functional>
template< typename T >
struct shared_ptr_comparator {
bool operator()(const std::shared_ptr<T> &a, const std::shared_ptr<T> &b) const {
return std::less<T>()(*a, *b);
}
};
void ptr_set_with_custom_comparator() {
std::set< std::shared_ptr<std::string>, shared_ptr_comparator<std::string> > ptr_set;
ptr_set.insert(std::make_shared<std::string>("world"));
ptr_set.insert(std::make_shared<std::string>("hello"));
ptr_set.insert(std::make_shared<std::string>("abc"));
for(auto const& entry : ptr_set) {
std::cout << *entry << std::endl;
}
}
void ptr_set_with_owner_less() {
std::set< std::shared_ptr<std::string>, std::owner_less<std::shared_ptr<std::string>> > ptr_set;
ptr_set.insert(std::make_shared<std::string>("world"));
ptr_set.insert(std::make_shared<std::string>("hello"));
ptr_set.insert(std::make_shared<std::string>("abc"));
for(auto const& entry : ptr_set) {
std::cout << *entry << std::endl;
}
}
void raw_set() {
std::set<std::string> raw_set;
raw_set.insert("world");
raw_set.insert("hello");
raw_set.insert("abc");
for(auto const& entry : raw_set) {
std::cout << entry << std::endl;
}
}
int main() {
std::cout << "A basic set of strings:" << std::endl;
raw_set();
std::cout << std::endl;
std::cout << "A set of shared_ptr<string>s with owner_less as the comparator:" << std::endl;
ptr_set_with_owner_less();
std::cout << std::endl;
std::cout << "A set of shared_ptr<string>s with the comparator shared_ptr_comparator:" << std::endl;
ptr_set_with_custom_comparator();
return 0;
}
上面的代码可以符合clang++ -Wall -std=c++11。这是输出:
A basic set of strings:
abc
hello
world
A set of shared_ptr<string>s with owner_less as the comparator:
world
hello
abc
A set of shared_ptr<string>s with the comparator shared_ptr_comparator:
abc
hello
world
这里,迭代和打印内容std::set 时的排序意味着正在比较_actual 基础值。上面示例的快速概览:
函数
raw_set只使用set<string>(不使用shared_ptr),仅供参考。我可以通过手写的
shared_ptr_comparator实现我想要的。使用它的函数ptr_set_with_custom_comparator按预期工作。函数
ptr_set_with_owner_less未按预期工作。owner_less(或owner_before)是否依赖于指针本身的地址/值?
我有两个问题:
STL 中是否存在与
shared_ptr_comparator(在上述程序中定义)等效的内容?我之所以这么问,是因为我写的比较器似乎是一个非常常见的用例,如果 STL 没有与之等效的东西,我会感到非常惊讶。owner_less 和 owner_before(它所调用的)究竟是做什么的?他们只是检查底层指针的等价性吗?我不确定我是否正确使用它。
提前感谢您对此问题的任何回答。
【问题讨论】:
-
您是否仔细阅读了标准C++ containers的相关文档?
标签: c++ c++11 stl shared-ptr comparator