提问人:nick 提问时间:3/16/2021 最后编辑:463035818_is_not_an_ainick 更新时间:3/16/2021 访问量:113
如何使指针在 std::set 中有效?
How can make pointer valid in std::set?
问:
我有一个自定义的结构,我重载运算符>:
struct A {
A(int a) : a_(a) {}
int a_;
friend operator > (const A& a) const {
return a_ > a.a_;
}
};
所以我可以将这个结构推入 STL 容器集:
std::set<A> s;
s.insert(A(3));
s.insert(A(5));
s.insert(A(4));
但是我正在做一项大任务,这意味着复制操作对我来说成本很高。
所以,我想用元素类型的指针构建一个集合,如下所示:
std::set<A*>s;
A a(3); A b(5); A c(4);
s.insert(&a); s.insert(&b); s.insert(&c);
但是我发现它无法保持顺序,有什么方法可以按元素指针保持顺序吗?
或者,我怎样才能将元素保存在有序的容器中,而不进行复制并具有良好的性能?
答:
3赞
m88
3/16/2021
#1
使用自定义比较器:
#include <iostream>
#include <set>
struct CustomCmp {
bool operator()(const int* lhs, const int* rhs) const {
return *lhs < *rhs;
}
};
int main()
{
int arr[] = { 3, 1, 4 };
std::set<int*, CustomCmp> mySet;
mySet.insert(&arr[0]);
mySet.insert(&arr[1]);
mySet.insert(&arr[2]);
for (auto& el: mySet) std::cout << *el << ' '; // 1, 3, 4
return 0;
}
评论
0赞
nick
3/16/2021
感谢 M88,但与使用 EmPlace 相比性能如何?
0赞
m88
3/16/2021
如果你的 A 类有一个 move-constructor,并且大致等价,否则只会复制 .(对指针来说根本没有区别)s.insert(A(n))
s.emplace(n);
insert
A(n)
0赞
m88
3/16/2021
@FrançoisAndrieux 我的意思是 [如果您想要一组 T* 像 T 一样排序,那么] 使用自定义比较器。话虽如此,除非 T 是我怀疑这真的是 OP 需要的,否则我同意。std::array<double,1'000'000>
0赞
François Andrieux
3/16/2021
@m88 对不起,我标记了错误的用户。我的意思是标记尼克。编辑:我用正确的@转发了我的评论。
0赞
François Andrieux
3/16/2021
@nick 您正在执行所谓的过早优化。您有两个类似的解决方案,目前尚不清楚哪种解决方案最适合您的特定用例。别担心,这是一个细节。使用最简单、最安全的解决方案,这是迄今为止最容易使用和最安全的解决方案。std::set<T>
评论
emplace
insert
operator<
operator>
s.emplace(3);
s.insert(A(3));