我们可以重载std::vector中的push_back()方法以允许非重复元素吗?我知道std::set和std::unordered_set应该避免重复的元素,但是std::set对元素进行排序,而std::unordered_set存储元素没有特定的顺序。我需要按插入的顺序检索元素,同时确保不插入重复的元素。
编辑:此问题here可能存在重复项。这个重复的最佳解决方案建议使用一个辅助数据结构和另一个自定义方法"add“。这对我来说并不好,因为(我将把它放在一个单独的文档中)在std::vector中插入数据的用户很少参考任何自定义函数的文档。但是,如果没有有效的方法,这可能是最后的办法。
发布于 2019-08-06 17:56:52
许多人建议不要这样做,但似乎有某种都市传说流传开来,认为这样做会导致宇宙经历真空衰变,而我们所知的现实将会融化。
您可以公开继承std::vector。但你必须考虑一下你能用它做些什么。
如果继承自vector,强烈建议您不要向其中添加任何数据成员。这可能会导致对象切片(谷歌"c++对象切片“。)您还需要记住,vector没有使用虚拟函数。这意味着您不能重写成员函数。您只能隐藏它们,所以不能保证调用的总是您的push_back()函数。例如,如果您将类的一个对象传递给某个引用vector的对象,则会调用原始对象。
因此,最后,您需要添加一个push_back_unique()函数。但这反过来意味着可以通过一个简单的免费函数来提供服务。所以不需要继承vector。这当然意味着永远不能保证向量中的元素是唯一的。其他代码可能会在其他地方使用push_back()。
如果您想要添加全新的方便函数,而这些函数不会强加或取消vector的任何限制,那么继承vector是有意义的。如果您想要看起来像vector但实际上不是的东西(因为它有不同的行为和/或限制),您应该实现自己的类型,通过私有继承或作为私有数据成员将容器功能委托给vector,然后通过公共包装函数复制vector API。
但这是非常乏味的实现。通常,您并不真正需要vector中的所有API。所以我想说的是,只需要围绕vector编写一个更小的类,它只提供您需要的功能。而且该功能听起来几乎是只读的,因为允许对元素的写访问允许将一个元素设置为与另一个元素相同的值,从而破坏了容器的唯一性。所以你可以这样做:
template<typename T>
class UniqueVector
{
public:
void push_back(T&& elem)
{
if (std::find(vec_.begin(), vec_.end(), elem) == vec_.end()) {
vec_.push_back(std::forward(elem));
}
}
const T& operator[](size_t index) const
{
return vec_[index];
}
auto begin() const
{
return vec_.cbegin();
}
auto end() const
{
return vec_.cend();
}
private:
std::vector<T> vec_;
};如果您仍然希望允许对单个元素进行写访问,那么可以提供非常量函数来检查传递的值是否已经存在于向量中。像这样:
void assign_if_unique(size_t index, T&& value)
{
if (std::find(vec_.begin(), vec_.end(), value) == vec_.end()) {
vec_[index] = std::forward(value);
}
}这是一个最小的例子。显然,你应该添加你真正想要的函数。比如size()、empty(),以及你需要的任何其他东西。
https://stackoverflow.com/questions/57372915
复制相似问题