扩展 std::vector 是个好主意吗?
Is it a good idea to extend std::vector?
稍微使用javascript
,我意识到与C++
相比,开发速度更快,因为由于通常不适用的原因而减慢了写作速度。总是通过.begin()
和.end()
通过我的所有应用程序是不舒服的。
我正在考虑扩展std::vector
(更多的是通过封装而不是继承),它主要可以遵循javascript
方法的约定,例如
.filter([](int i){return i>=0;})
.indexOf(txt2)
.join(delim)
.reverse()
而不是
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());
但是,我想知道这是否是一个好主意,为什么已经没有C++
库用于这种常见的日常功能?这样的想法有什么问题吗?
这个想法没有任何继承性错误,除非你尝试多态地删除向量。
例如:
auto myvec = new MyVector<int>;
std::vector<int>* myvecbase = myvec;
delete myvecbase; // bad! UB
delete myvec; // ok, not UB
这是不寻常的,但仍可能是错误的源头。
但是,我仍然不推荐它。
要获得添加的功能,您必须拥有自己的向量的实例,这意味着您必须将任何其他现有向量复制或移动到您的类型中。它不允许将函数与向量的引用一起使用。
例如,请考虑以下代码:
// 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();
此外,它仅适用于矢量,而我可以看到该实用程序在其他容器类型中具有这些功能。
我的建议是让你提出的函数自由 - 而不是让它们成为你的子向量类的成员。这将使它们适用于任何实例或引用,并且还可以重载其他容器类型。这将使你的代码更标准(不使用你自己的容器集),并且更容易维护。
如果你觉得需要为容器类型实现许多函数式实用程序,我建议你寻找一个为你实现它们的库,即ranges-v3
,它正在走向标准化。
在参数的另一边,有继承 STL 类的有效用例。例如,如果处理泛型代码并希望存储可能为空的函数对象,则可以从std::tuple
(私下)继承以利用空基类优化。
此外,我有时碰巧存储特定数量的相同类型的元素,这些元素在编译时可能会有所不同。我确实扩展了std::array
(私下)以简化实施。
但是请注意这两种情况:我使用它们来简化泛型代码的实现,并且我私下继承了它们,这不会将继承暴露给其他类。
包装器可用于创建更流畅的 API。
template<typename container >
class wrapper{
public:
wrapper(container const& c) : c_( c ){}
wrapper& reverse() {
std::reverse(c_.begin(), c_.end());
return *this;
}
template<typename it>
wrapper& copy( it& dest ) {
std::copy(c_.begin(), c_.end(), dest );
return *this;
}
/// ...
private:
container c_;
};
然后可以使用包装器来"美化"代码
std::vector<int> ints{ 1, 2, 3, 4 };
auto w = wrapper(ints);
auto out = std::ostream_iterator<int>(std::cout,", ");
w.reverse().copy( out );
在此处查看工作版本。
- 什么时候在C++中返回常量引用是个好主意
- 使用嵌套函数数组是个好主意吗?
- 将std::regex设置为静态的好主意吗
- 使用共享库进行变体处理是个好主意吗?
- 使用列表<Byte>不是好主意吗?
- 用C++编写多级内联函数是个好主意吗?
- 重载参数 C++ 是个好主意吗?
- 扩展 std::vector 是个好主意吗?
- 将 int32_t 键入为 int 是个好主意吗?
- 常量参考延长对象的寿命,然后是const_cast,这是一个好主意吗?
- 使用 QT 开发服务器应用程序是个好主意吗?(QT5)
- 用 constexpr 中的工会取代reinterpret_cast - 好主意?
- 将C 11设置功能更改为带有转发的现代模板功能是一个好主意
- 在哪里使用"std::valarray"是个好主意?
- std :: tr1 :: shared_ptr throw bad_alloc,也是一个好主意
- 在构造函数中循环C++是一个好主意吗?
- 让std::for_each更有用——这是让函子知道当前索引的好主意吗
- 一个尝试非确定性有限状态机(c++),是静态std::map的好主意
- 有一个指向std::vector-element的指针,该指针目前还不存在,但稍后将被构造,这是个好主意吗?
- 什么时候使用std::promise优于其他std::线程机制是一个好主意?