簡體   English   中英

擴展std :: vector是個好主意嗎?

[英]Is it a good idea to extend std::vector?

使用javascript略微工作,我意識到與C++相比,開發速度更快,因為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 );

這里查看工作版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM