扩展std :: vector是个好主意吗?

vic*_*ica 7 c++ stl

稍微合作javascript,我意识到开发速度更快,相比之下,C++由于通常不适用的原因导致写入速度变慢.总是通过.begin()并且.end()通过我的所有应用程序发生这种情况并不舒服.

我正在考虑扩展std::vector(更多是通过封装而不是继承),这些扩展主要遵循javascript方法的惯例,例如

.filter([](int i){return i>=0;})
.indexOf(txt2)
.join(delim)
.reverse()
Run Code Online (Sandbox Code Playgroud)

代替

auto it = std::copy_if (foo.begin(), foo.end(), std::back_inserter(bar), [](int i){return i>=0;} );

ptrdiff_t pos = find(Names.begin(), Names.end(), old_name_) - Names.begin();

copy(elems.begin(), elems.end(), ostream_iterator<string>(s, delim)); 

std::reverse(a.begin(), a.end());
Run Code Online (Sandbox Code Playgroud)

但是,我想知道这是不是一个好主意,为什么已经没有C++这种常见日常功能的库?这样的想法有什么问题吗?

Gui*_*cot 4

这个想法没有什么本质上的错误,除非您尝试以多态方式删除向量。

例如:

auto myvec = new MyVector<int>;
std::vector<int>* myvecbase = myvec;

delete myvecbase; // bad! UB
delete myvec; // ok, not UB
Run Code Online (Sandbox Code Playgroud)

这是不寻常的,但仍然可能是错误的来源。

但是,我仍然推荐它。

为了获得附加功能,您必须拥有自己的向量的实例,这意味着您必须将任何其他现有向量复制或移动到您的类型。它不允许您将函数与向量的引用一起使用。

例如考虑以下代码:

// Code not in your control:
std::vector<int>& get_vec();

// error! std::vector doesn't have reverse!
auto reversed = get_vec().reverse();

// Works if you copy the vector to your class
auto copy_vec = MyVector<int>{get_vec()};
auto reversed_copy = copy_vec.reverse();
Run Code Online (Sandbox Code Playgroud)

此外,它仅适用于矢量,而我可以看到该实用程序具有其他容器类型的这些功能。


我的建议是让你提出的函数免费 - 不要让它们成为你的向量子类的成员。这将使它们能够与任何实例或引用一起使用,并且还可以与其他容器类型一起重载。这将使您的代码更加标准(不使用您自己的一组容器)并且更易于维护。

如果您觉得需要为容器类型实现许多函数式实用程序,我建议您寻找一个可以为您实现它们的库,即ranges-v3,它正在走向标准化。


另一方面,继承 STL 类有有效的用例。例如,如果您处理通用代码并希望存储可能为空的函数对象,则可以std::tuple(私有)继承以利用空基类优化。

另外,我有时会存储特定数量的相同类型的元素,这些元素在编译时可能会有所不同。我std::array确实(私下)进行了扩展以简化实施。

但是请注意这两种情况:我使用它们来简化通用代码的实现,并且我私下继承了它们,这不会将继承公开给其他类。