英文:
Why are the elements of the std::multimap changing after exiting the loop in this code?
问题
I am trying to implement a transparency in my OpenGL program. Currently I have such function (minimal reproducible example):
#include <map>
#include <unordered_map>
#include <iostream>
#include <vector>
class Sprite
{
public:
std::vector<int> m_meshes;
std::pair<float, float> pos;
};
int main()
{
std::unordered_map<int, Sprite> m_sprites = {
{ 0, { { 43 } } },
{ 1, { { 234 } } }
};
std::multimap<int, const Sprite*, std::greater<int>> translucentSprites{};
for (const std::pair<int, Sprite>& spritePair : m_sprites)
{
translucentSprites.insert({ spritePair.second.pos.first + spritePair.second.pos.second, &spritePair.second});
std::cout << translucentSprites.begin()->second->m_meshes.size() << ' ';
}
std::cout << translucentSprites.begin()->second->m_meshes.size() << '\n';
return 0;
}
After running this code, I get the following result:
1 1 0
The first two numbers are 1, but the third number for some reason is 0, not 1. I tried to use the debugger, but it did not help. What is my mistake here?
英文:
I am trying to implement a transparency in my OpenGL prorgam. Currently I have such function (minimal reproducible example):
#include <map>
#include <unordered_map>
#include <iostream>
#include <vector>
class Sprite
{
public:
std::vector<int> m_meshes;
std::pair<float, float> pos;
};
int main()
{
std::unordered_map<int, Sprite> m_sprites = {
{ 0, { { 43 } } },
{ 1, { { 234 } } }
};
std::multimap<int, const Sprite*, std::greater<int>> translucentSprites{};
for (const std::pair<int, Sprite>& spritePair : m_sprites)
{
translucentSprites.insert({ spritePair.second.pos.first + spritePair.second.pos.second, &spritePair.second});
std::cout << translucentSprites.begin()->second->m_meshes.size() << ' ';
}
std::cout << translucentSprites.begin()->second->m_meshes.size() << '\n';
return 0;
}
After running of this code, I get the following result:
1 1 0
The first two numbers are 1, but the third number for some reason is 0, not 1. I tried to use debugger, but it did not help. What is my mistake here?
答案1
得分: 5
当const std::pair<int, Sprite>& spritePair
超出范围(在每次迭代中),Sprite
的 副本 将消失,指针将悬空。
您可以通过将其修改为
const std::pair<const int, Sprite>& spritePair
来修复它,这样将引用映射中的实际 pair
,而不是通过转换创建 std::pair<int, Sprite>
。
另一种替代方法是使用结构化绑定:
for (const auto& [idx, sprite] : m_sprites) {
translucentSprites.insert({sprite.pos.first + sprite.pos.second, &sprite});
一个简化方法是使用 emplace
而不是 insert
:
translucentSprites.emplace(sprite.pos.first + sprite.pos.second, &sprite);
英文:
When const std::pair<int, Sprite>& spritePair
goes out of scope (in each iteration), the copy of the Sprite
will be gone and the pointer will be dangling.
You can fix it by making it
const std::pair<const int, Sprite>& spritePair
which would then reference the actual pair
in the map instead of creating a std::pair<int, Sprite>
via conversion.
An alternative fix is to use structured bindings:
for (const auto& [idx, sprite] : m_sprites) {
translucentSprites.insert({sprite.pos.first + sprite.pos.second, &sprite});
A simplification could be to use emplace
instead of insert
:
translucentSprites.emplace(sprite.pos.first + sprite.pos.second, &sprite);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论