插入期间容器std::set的行为
Behaviour of container std::set during Insertion?
插入一个集合时,该集合内部是否多次删除某些对象?我试着像下面的程序一样插入两个MyClass类型的对象,但令我惊讶的是,它调用了类的析构函数,初始插入值2次!我无法理解这背后的逻辑。谁能给点输出的建议?(以粗体突出显示)
#include<stdio.h>
#include<stdlib.h>
#include<set>
using namespace std;
struct MyClass
{
double num;
~MyClass()
{
printf("Destructor called..for val: %lfn", num);
}
};
typedef int (*fun_comp)(MyClass, MyClass);
int
comp(MyClass a, MyClass b)
{
return a.num-b.num;
}
int
main()
{
fun_comp fptr;
fptr = ∁
set<MyClass, int (*)(MyClass, MyClass)> b(fptr);
for(int i=3; i< 5; i++)
{
printf("started with i: %d....nn", i);
{
MyClass m;
m.num=i*1.134;
b.insert(m);
printf("Inserted val: %lfn", m.num);
}
printf("ended....nn");
}
printf("Done with insert..n");
return 0;
}
输出:以i开头:3....
插入值:3.402000
为val: 3.402000
结束……
以i: 4开头....
析构函数调用..for val: 4.536000 <-------为什么在插入前释放
析构函数调用..for val: 3.402000 <-------多次调用此值对象的析构函数
析构函数. .呼吁val: 4.536000 & lt ;-------- ??
析构函数. .呼吁val: 3.402000 & lt;——了! !
插入值:4.536000
for val: 4.536000
结束……
插入完成
为val: 3.402000
比较器
int
comp(MyClass a, MyClass b)
{
return a.num-b.num;
}
按值接受其形参。这将创建额外的副本,然后销毁。
通过引用传递会更好。
将比较函数改为使用(const)引用
int comp(const MyClass& a, const MyClass& b)
{
return a.num-b.num;
}
每次compp被调用时,它都会创建a和b的副本。当compp退出时,这些副本将被销毁。
除了上述几点之外,您的比较函数是无效的,因为它没有指定值的一致顺序。如果a.num=1且b.num=2,则comp(a,b)为真,即a"出现在"b之前,并且comp(b,a)也为真,即b"出现在"a之前。这使得set的行为未定义。
最好为MyClass创建一个小于操作符,并让set<>的默认比较函数完成这项工作:struct MyClass{双num;
~MyClass()
{
printf("Destructor called..for val: %lfn", num);
}
bool operator < (const MyClass &rhs) const
{
return num < rhs.num;
}
};
...
set<MyClass> b;
相关文章:
- 在声明中合并两个常量"std::set"(不是在运行时)
- 有没有办法对std::unordered_set、std::unrdered_map、std::set、std::map
- 将 std::set 与基于键的比较器一起使用
- 修改"std::set"中用户定义类型的值
- 如何在构造函数参数中初始化"std::set"?
- 如何使用 lower_bound/upper_bound 从 std::set 获取索引号?
- 如何在 C++ 中转发声明 std::set?
- 重构使用动态强制转换的 std::set 的比较运算符
- 为什么 std::set.erase(first, last) 会影响从中获取 (first, last) 的容器?
- 将 std:set<int32_t> 复制到 std::set <uint32_t>的好方法
- 错误 C2676:std::set::const_iterator 没有运算符 + 函数?
- std::set 是否将对象连续存储在内存中?
- google test PrintTo for std::set<std::string>
- 不能对 std::set<std::string, std::less 使用用户提供的比较函数<>>
- "Flattening" std::set<std::string> 用于存储和比较?
- C++ std::map<std::string, std::set<std::string>> .如何循环设置值?
- 在std::set/std::map中存储具有多个不同类型字段的c++对象的有效方法
- 在C++中迭代 std::set<std::string> 时出现分段错误
- 从声明为 std::set<std::shared_ptr> edges_ 的edges_中删除边<Edge>;
- 将基于范围的 for 与 std::set<std::unique_ptr <T>一起使用>已删除函数