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

时间:2018-03-02 05:37:12

标签: c++ stl

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++库了?这个想法有什么问题吗?

2 个答案:

答案 0 :(得分:4)

除非您尝试以多态方式删除矢量,否则这个想法没有任何遗传错误。

例如:

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();

此外,它只适用于vector,而我可以看到该实用程序将这些功能与其他容器类型一起使用。

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

如果您觉得需要为容器类型实现许多功能样式实用程序,我建议您寻找一个为您实现它们的库,即ranges-v3,它正在进行标准化。

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

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

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

答案 1 :(得分:2)

包装器可用于创建更流畅的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_;
};

然后可以使用包装纸来美化&#34;代码

std::vector<int> ints{ 1, 2, 3, 4 };

auto w = wrapper(ints);    
auto out = std::ostream_iterator<int>(std::cout,", ");

w.reverse().copy( out );

查看工作版here