![](/img/trans.png)
[英]Is it a good idea to have a pointer to a std::vector-element that not does not exist just yet but will be construct later?
[英]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.