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

cod*_*ool 3 c++ stl find

我在编程中经常使用向量,并且通常遍历一个现有值的向量,我使用std :: find,如下所示:

std::vector<int> foo;
std::vector<int>::iterator pos( std::find( foo.begin(), foo.end(), bar );
Run Code Online (Sandbox Code Playgroud)

这是一个真正的问题.所以我从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 );
    }
};
Run Code Online (Sandbox Code Playgroud)

所以现在我可以更自然地找到它:

foovector<int> foo;
foovector<int>::iterator pos( foo.find( bar ) );
Run Code Online (Sandbox Code Playgroud)

我的问题是,这似乎是向量的一个自然而明显的扩展,那么为什么它不是STL的一部分甚至是提升?我觉得我在这里错过了一些奥术知识.

Ste*_*end 6

  1. 继承STL容器并不是一个好主意 - 它们没有虚拟析构函数,因为它们不是为此而设计的.

  2. <vector>的强度不是它的可搜索性 - 还有其他专门用于此的容器.

  3. 我怀疑大多数人只是找不到你要替换的代码那么麻烦.


Lou*_*nco 5

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

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


Arm*_*yan 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 );
 }
Run Code Online (Sandbox Code Playgroud)

你可以将它放入命名空间std(从技术上讲是不允许),或者在其他一些命名空间中(ADL不会找到它的权衡,所以你需要对其进行限定).HTH

PS的方式可以概括为所有容器

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

  • @Inverse:我们想要的是"基于范围"的算法.参见Alexandrescu的"Iterators Must Go"和Boost.Range. (2认同)