std :: find vs.从矢量派生模板

时间:2010-10-12 15:52:18

标签: c++ stl find

我在编程中经常使用向量,并且通常遍历一个现有值的向量,我使用 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 甚至提升的一部分?我觉得我在这里错过了一些奥术知识。

6 个答案:

答案 0 :(得分:6)

  1. 继承自STL容器not considered a great idea - 它们没有虚拟析构函数,因为它们不是为此设计的。

  2. &lt; vector&gt;的强度不是它的可搜索性 - 还有其他专门用于此的容器。

  3. 我怀疑大多数人都没有找到你要替换的代码,这很麻烦。

答案 1 :(得分:5)

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

然后,他们在迭代器(而不是集合)上添加模板函数。这意味着,只要您提供标准迭代器,即使您创建自己的集合,其中许多函数也能正常工作。你不需要继承来使这项工作 - 所以事情可以分开。

答案 2 :(得分:5)

你做了什么,你想做什么,仍然没有进入从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 );
}

答案 3 :(得分:2)

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

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

答案 4 :(得分:1)

因为如果您通常需要执行大量查找,则应使用集合或映射(或者任何一个的散列版本)。它不仅更容易编写,而且O(log n)找到复杂性,而未排序的向量是O(n)

使用地图:

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

Set类似。

答案 5 :(得分:1)

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

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

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(如果可用的话)...