std::unique 未按预期使用结构
std::unique not working as expected with struct
我目前正在开发一款由边定义关卡的 2D 游戏:
struct Edge
{
vec2int start;
vec2int end;
}
结构 vec2int
是一个具有 x、y 坐标的向量,并且重载了所有需要的运算符(在这种特殊情况下 operator==
)。
由于存储网格内部边缘的数据结构,网格内的不同单元格中可能存在重复的边缘。当将它们组合回一个 std::vector<Edge>
时,我试图像这样摆脱它们:
auto it = std::unique(
edges.begin(),
edges.end(),
[&](const Edge& e1, const Edge& e2)
{
return e1.start == e2.start && e1.end == e2.end;
});
edges.resize(std::distance(edges.begin(), it));
无论出于何种原因,这只会删除一些(或 none)的重复边。我不知道为什么。关于 std::unique
我是否遗漏了什么?
代码:
#include <algorithm>
#include <iostream>
#include <vector>
template<class T>
struct v2d_generic
{
T x = 0;
T y = 0;
bool operator==(const v2d_generic& rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
bool operator!=(const v2d_generic& rhs) const
{
return (this->x != rhs.x || this->y != rhs.y);
}
};
typedef v2d_generic<int> vec2i;
struct Edge
{
vec2i start;
vec2i end;
};
int main(void)
{
std::vector<Edge> edges;
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 1}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 2}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 1}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 2}});
std::cout << edges.size() << std::endl;
auto it = std::unique(
edges.begin(),
edges.end(),
[&](const Edge& e1, const Edge& e2)
{
return e1.start == e2.start && e1.end == e2.end;
});
edges.resize(std::distance(edges.begin(), it));
std::cout << edges.size() << std::endl;
}
这两次输出 4。
std::unique
删除 连续 个等效元素。在你的例子中,你没有连续相等的元素,所以它不应该删除任何东西。
如果您不关心范围内元素的顺序,可以在调用 std::unique
之前对其进行排序。
我目前正在开发一款由边定义关卡的 2D 游戏:
struct Edge
{
vec2int start;
vec2int end;
}
结构 vec2int
是一个具有 x、y 坐标的向量,并且重载了所有需要的运算符(在这种特殊情况下 operator==
)。
由于存储网格内部边缘的数据结构,网格内的不同单元格中可能存在重复的边缘。当将它们组合回一个 std::vector<Edge>
时,我试图像这样摆脱它们:
auto it = std::unique(
edges.begin(),
edges.end(),
[&](const Edge& e1, const Edge& e2)
{
return e1.start == e2.start && e1.end == e2.end;
});
edges.resize(std::distance(edges.begin(), it));
无论出于何种原因,这只会删除一些(或 none)的重复边。我不知道为什么。关于 std::unique
我是否遗漏了什么?
代码:
#include <algorithm>
#include <iostream>
#include <vector>
template<class T>
struct v2d_generic
{
T x = 0;
T y = 0;
bool operator==(const v2d_generic& rhs) const
{
return (this->x == rhs.x && this->y == rhs.y);
}
bool operator!=(const v2d_generic& rhs) const
{
return (this->x != rhs.x || this->y != rhs.y);
}
};
typedef v2d_generic<int> vec2i;
struct Edge
{
vec2i start;
vec2i end;
};
int main(void)
{
std::vector<Edge> edges;
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 1}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 2}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 1}});
edges.push_back(Edge{vec2i{1, 1}, vec2i{1, 2}});
std::cout << edges.size() << std::endl;
auto it = std::unique(
edges.begin(),
edges.end(),
[&](const Edge& e1, const Edge& e2)
{
return e1.start == e2.start && e1.end == e2.end;
});
edges.resize(std::distance(edges.begin(), it));
std::cout << edges.size() << std::endl;
}
这两次输出 4。
std::unique
删除 连续 个等效元素。在你的例子中,你没有连续相等的元素,所以它不应该删除任何东西。
如果您不关心范围内元素的顺序,可以在调用 std::unique
之前对其进行排序。