std::find 与从向量派生模板

发布于 2024-09-27 03:22:07 字数 799 浏览 2 评论 0原文

我在编程中经常使用向量,并且通常为了遍历向量来获取现有值,我使用 std::find ,如下所示:

std::vector<int> foo;
std::vector<int>::iterator pos( std::find( foo.begin(), foo.end(), bar );

这是一个真正的无聊。所以我从 std::vector 派生一个模板来提供 find 方法:

template<class T>
class foovector : public std::vector<T>
{
public:
    typename std::vector<T>::iterator find( const T& value )
    {
        return std::find( this->begin(), this->end(), value );
    }
};

所以现在我可以更自然地进行查找:

foovector<int> foo;
foovector<int>::iterator pos( foo.find( bar ) );

我的问题是,这似乎是一个向量的自然且明显的扩展,那么为什么它不是 STL 甚至 boost 的一部分呢?我觉得我在这里缺少一些奥术知识。

I use vectors a lot in my programming, and generally to traverse a vector for an existing value I use std::find as in:

std::vector<int> foo;
std::vector<int>::iterator pos( std::find( foo.begin(), foo.end(), bar );

This is a real bore. So I went to deriving a template from std::vector to provide a find method:

template<class T>
class foovector : public std::vector<T>
{
public:
    typename std::vector<T>::iterator find( const T& value )
    {
        return std::find( this->begin(), this->end(), value );
    }
};

And so now I can do find's more naturally:

foovector<int> foo;
foovector<int>::iterator pos( foo.find( bar ) );

My question is that this seems such a natural and obvious extension to vector, so why isn't it part of the STL or even boost? I feel like I'm missing some Arcane Knowledge here.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一抹微笑 2024-10-04 03:22:07

如果你做了你想要实现的事情,但仍然不进入从 std::vector 继承的可疑路径,

定义一个独立的函数,

template <typename T>
typename std::vector<T>::const_iterator find( const std::vector<T>& v, const T& value )
 {
     return std::find( v.begin(), v.end(), value );
 }

你可以将其放入命名空间 std(从技术上讲,这是不允许的),或在其他命名空间中(代价是 ADL 无法找到它,因此您需要对其进行限定)。 HTH

P.S.顺便说一句,你可以将其推广到所有容器

template <typename Container, typename T>
typename Container::const_iterator find( const Container& c, const T& value )
{
     return std::find( c.begin(), c.end(), value );
}

What about you do what you want to achieve and still not go into the dubious path of inheriting from std::vector

define a freestanding function

template <typename T>
typename std::vector<T>::const_iterator find( const std::vector<T>& v, const T& value )
 {
     return std::find( v.begin(), v.end(), value );
 }

you can put this into namespace std(which, technically speaking is not allowed), or in some other namespace (with the tradeoff that it won't be found by ADL, so you will need to qualify it). HTH

P.S. by the way you could generalize this for all containers

template <typename Container, typename T>
typename Container::const_iterator find( const Container& c, const T& value )
{
     return std::find( c.begin(), c.end(), value );
}
白色秋天 2024-10-04 03:22:07
  1. 从 STL 容器继承不被认为是一个好主意 -它们没有虚拟析构函数,因为它们不是为此设计的。

  2. 的优势不在于其可搜索性 - 还有其他专门用于此目的的容器。

  3. 我怀疑大多数人只是不觉得您要替换的代码那么麻烦。

  1. Inheriting from STL containers is not considered a great idea - they don't have virtual destructors since they were not designed for this.

  2. <vector>'s strength is not its searchability - there are other containers specialized for that.

  3. I suspect that most people just don't find the code you are replacing that bothersome.

尛丟丟 2024-10-04 03:22:07

STL 设计是提供具有狭窄接口的集合,该接口仅实现在不访问私有成员的情况下无法实现的方法。

然后,他们在迭代器(而不是集合)上添加模板函数。这意味着,即使您创建自己的集合,只要提供标准迭代器,其中许多函数也可以很好地工作。您不需要继承来完成这项工作——因此事情可以保持独立。

The STL design is to provide collections that have a narrow interface that only implements methods that you cannot implement without access to private members.

Then, they add template functions on iterators (not collections). This means that many of those functions work well even if you make your own collection as long as you provide standard iterators. You don't need inheritance to make this work -- so things can stay separate.

吃→可爱长大的 2024-10-04 03:22:07

可能是因为向量是最简单的容器类型,如果优先考虑搜索,则可以使用更好的(关联)容器。

如果您按索引搜索,Vector 具有 O(1) 性能,但如果您使用搜索算法,您将失去所有这些好处。

Possibly because vector is the simplest type of container and there are better (associative) containers to use if searching is a priority.

Vector has O(1) performance if you search by index, but if you use a search algorithm, you lose all that benefit.

鹿! 2024-10-04 03:22:07

因为如果您通常需要进行大量查找,则应该使用集合或映射(或两者的哈希版本)。它不仅更容易编写,而且复杂度为 O(log n),而未排序的向量为 O(n)

与地图:

map<stuff> m
m[bar] // returns a reference to the element with key bar.

设置类似。

Because if you typically need to do a lot of finds, you should use a set or map (or a hashed version of either). Not only is it easier to write, but these have O(log n) find complexity, whereas an unsorted vector is O(n).

With map:

map<stuff> m
m[bar] // returns a reference to the element with key bar.

Set is similar.

汐鸠 2024-10-04 03:22:07

实际上,我已经将 中定义的大部分自由函数包装为采用容器/范围而不是迭代器的版本。它不仅更安全(我可以添加简单的检查,确保范围有效,等等......)而且也更方便。

对于您的情况,执行此操作的通用方法是:

template <typename Container>
typename Container::iterator find(Container& c,
                                  typename Container::value_type const& v)
{
  return std::find(c.begin(), c.end(), v);
}

template <typename Container>
typename Container::const_iterator find(Container const& c,
                                        typename Container::value_type const& v)
{
  return std::find(c.begin(), c.end(), v);
}

这可以与任何符合 STL 的容器一起使用。

当然,最好是通过 Concept 来调整它,以便使用成员函数 find(如果可用)......

Actually, I have wrapped most of the free functions defined in <algorithm> with versions taking containers / ranges instead of iterators. Not only is it much safer (I can add simple checks, make sure the range is valid, etc...) it's also much more convenient.

For your case, the generic way to do this is:

template <typename Container>
typename Container::iterator find(Container& c,
                                  typename Container::value_type const& v)
{
  return std::find(c.begin(), c.end(), v);
}

template <typename Container>
typename Container::const_iterator find(Container const& c,
                                        typename Container::value_type const& v)
{
  return std::find(c.begin(), c.end(), v);
}

This can be used with any STL-compliant container.

Of course, what would be nice would be to adapt this through Concept in order to use the member function find if available...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文