2 回答

TA貢獻1818條經驗 獲得超8個贊
我希望我能找到一個可以接受的答案。不幸的是,在 C++ 中,你不能operator[]用多個參數重載,所以我operator()改用了。
#include <iostream>
#include <vector>
template <typename T>
class WrapperVector
{
private:
std::vector<T> data;
public:
WrapperVector(size_t reserve_size)
{
data.reserve(reserve_size);
}
WrapperVector(typename std::vector<T>::iterator start, typename std::vector<T>::iterator end)
{
data = std::vector<T>(start, end);
}
// appends element to the end of container, just like in Python
void append(T element)
{
data.push_back(element);
}
/* instead of operator[], operator() must be used
because operator[] can't accept more than one argument */
// instead of self[x:y], use this(x, y)
WrapperVector<T> operator()(size_t start, size_t end)
{
return WrapperVector<T>(data.begin() + start, data.begin() + end);
}
// instead of self[x:], use this(x)
WrapperVector<T> operator()(size_t start)
{
return WrapperVector<T>(data.begin() + start, data.end());
}
// prints all elements to cout
void print()
{
if (!data.size())
{
std::cout << "No elements.\n";
return;
}
std::cout << data[0];
size_t length = data.size();
for(size_t i=1; i < length; i++)
std::cout << ' ' << data[i];
std::cout << '\n';
}
};
int main()
{
WrapperVector<int> w(5);
w.append(1);
w.append(2);
w.append(3);
w.append(4);
w.append(5);
w(0).print();
w(1, 3).print();
// you can also save the slice
WrapperVector<int> w2 = w(2);
WrapperVector<int> w3 = w(2, 4);
w2.print();
w3.print();
return 0;
}
現在您甚至可以重載它以接受三個參數來解釋step,就像在 Python 中一樣。我把它作為一個練習給你。

TA貢獻1876條經驗 獲得超5個贊
您可以使用迭代器的概念,而不是創建一個引入一些維護和某些限制的自定義類。兩個迭代器用于表示一系列值。例如函數
template<typename TIterator> foo(TIterator start, TIterator end);
將采用僅由兩個迭代器指定的對象范圍。它是一個模板,因此它可以從不同的容器中獲取迭代器。要從以這種方式給定的范圍中選擇子范圍,您可以使用std::next()
和std::prev()
。例如對于一個
std::vector<int> list;
您可以使用從第三個元素開始的子范圍調用 foo :
foo(std::next(list.begin(), 2), list.end());
或使用從第三個到倒數第二個元素的子范圍調用 foo:
foo(std::next(list.begin(), 2), std::prev(list.end(), 1));
如果您需要/想要復制子范圍,您可以輕松地做到這一點。例如
std::vector<int> subList(std::next(list.begin(), 2), std::prev(list.end(), 1));
將創建一個向量sublist
,其中包含來自 的倒數第三個到倒數第二個元素list
。
當然,這些只是簡單的例子。在現實世界的應用程序中,您需要檢查這些子范圍是否有效/存在。
優點是:
沒有額外的包裝類
無需復制任何數據(僅迭代器本身)
標準庫幾乎只使用迭代器來表示范圍,所以最好堅持這個概念。
使用模板,您可以輕松地支持標準庫中的所有容器,只要它們的迭代器滿足參考中列出的要求。(您可以將上述示例與以及大多數其他容器一起使用
std::array
,std::list
無需任何修改,list
原因類型除外)迭代器是用戶或第三方容器的接口,只要它們提供滿足參考中列出的要求的迭代器。
另一方面:
代碼變得有點復雜
理解迭代器可能需要一些時間,因為它與其他語言使用的概念完全不同。
添加回答
舉報