是否有 std::set(或 std::map)的 STL 比较器和 shared_ptr 键提供基于值的查找? std::owner_less 到底是做什么的?
Is there an STL comparator for std::set (or std::map) with shared_ptr keys that provides value-based lookups? What exactly does std::owner_less do?
我有一个带有 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
)是否依赖指针本身的addresses/values?
我有两个问题:
STL 中是否存在任何等同于 shared_ptr_comparator
(在上述程序中定义)的东西?我问是因为我写的比较器似乎是一个非常常见的用例,如果 STL 没有与之等效的东西,我会感到非常惊讶。
owner_less and owner_before(它称之为)究竟是做什么的?他们只是检查底层指针的等价性吗?不知道我用的对不对
提前感谢您对此问题的任何回答。
Does anything equivalent to shared_ptr_comparator (defined in the program above), exist in the STL? I ask because the comparator I wrote seems like a really common use case, and I would be very surprised if the STL didn't have anything equivalent to it.
我也很惊讶,但是不,STL 没有内置的指针比较器以这种方式工作。然而,有更好的方法来实现它,它允许传递任何指针。
template<typename T, typename comp_t>
bool ptr_compare(T lhs, T rhs, comp_t comp) {
return comp(*lhs, *rhs);
}
你可以这样称呼它:
ptr_compare(a_ptr, b_ptr, std::less<int>())
如果您想要一个与 STL 容器兼容的版本:
template<typename T>
bool ptr_less(T lhs, T rhs) {
return std::less<decltype(*lhs)>()(*lhs, *rhs);
}
What exactly does owner_less and owner_before (which it calls) do? Do they simply check for equivalence of the underlying pointers? I'm not sure if I'm using it right.
std::owner_less
不是按价值比较,而是按所有者比较,所以与你的问题无关。
std::shared_ptr<T>::owner_before
被 std::owner_less
调用以找出顺序。
我有一个带有 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
)是否依赖指针本身的addresses/values?
我有两个问题:
STL 中是否存在任何等同于
shared_ptr_comparator
(在上述程序中定义)的东西?我问是因为我写的比较器似乎是一个非常常见的用例,如果 STL 没有与之等效的东西,我会感到非常惊讶。owner_less and owner_before(它称之为)究竟是做什么的?他们只是检查底层指针的等价性吗?不知道我用的对不对
提前感谢您对此问题的任何回答。
Does anything equivalent to shared_ptr_comparator (defined in the program above), exist in the STL? I ask because the comparator I wrote seems like a really common use case, and I would be very surprised if the STL didn't have anything equivalent to it.
我也很惊讶,但是不,STL 没有内置的指针比较器以这种方式工作。然而,有更好的方法来实现它,它允许传递任何指针。
template<typename T, typename comp_t>
bool ptr_compare(T lhs, T rhs, comp_t comp) {
return comp(*lhs, *rhs);
}
你可以这样称呼它:
ptr_compare(a_ptr, b_ptr, std::less<int>())
如果您想要一个与 STL 容器兼容的版本:
template<typename T>
bool ptr_less(T lhs, T rhs) {
return std::less<decltype(*lhs)>()(*lhs, *rhs);
}
What exactly does owner_less and owner_before (which it calls) do? Do they simply check for equivalence of the underlying pointers? I'm not sure if I'm using it right.
std::owner_less
不是按价值比较,而是按所有者比较,所以与你的问题无关。
std::shared_ptr<T>::owner_before
被 std::owner_less
调用以找出顺序。