如何为C++模板类实现begin和end方法以支持范围for循环
自定义C++模板类实现范围for循环的正确方式
我需要给自定义C++模板类container实现begin和end方法,让它支持范围for循环遍历内部数组,但不知道具体怎么写。我写了一段代码,但没法正常工作,希望能实现像for(const char& c : my_container)这样的遍历。
我的错误代码如下:
template <typename T> class container { public: size_t n; T *p; container(std::initializer_list<T> L) { int i = 0; n = L.size(); p = new T[n]; for(auto element : L) { p[i] = element; i++; } } T getArray() { return *p; } T *begin(container<T> &cref); T *end(container<T> &cref); ~container() { delete[] p; } T &operator[](size_t k) { return p[k]; } void info() { std::cout << "Ilość elementów w tablicy: " << n << "\n"; for(const char& c : p) { std::cout << c << std::endl; } std::cout << "Typ danych: " << typeid(*p).name() << '\n'; }; size_t length() const { return n; } }; template <typename T> T* container<T>::begin(container<T> &cref) { return cref.getArray()[0]; } template <typename T> T* container<T>::end(container<T> &cref) { return cref.getArray()[0 + cref.length()]; } int main(int argc, char** argv) { container<char> Z{'a', 'b', 'c', 'd'}; Z.info(); std::cout << Z.length(); return 0; }
问题分析
begin和end被定义成需要接收容器引用的函数,但它们应该是容器的成员函数,直接访问类内部的p和n即可getArray函数返回的是*p(数组第一个元素的值)而非指针,导致后续地址计算完全错误info函数里的for(const char& c : p)写法错误,p是指针,不能直接用于范围for循环,应该遍历容器对象本身- 缺少
const版本的begin和end,无法支持const容器的遍历
正确实现代码
#include <iostream> #include <initializer_list> #include <typeinfo> template <typename T> class container { public: size_t n; T *p; // 构造函数 container(std::initializer_list<T> L) { n = L.size(); p = new T[n]; size_t i = 0; for(auto element : L) { p[i++] = element; } } // 非const版本的begin和end T* begin() { return p; } T* end() { return p + n; } // const版本的begin和end,支持const容器遍历 const T* begin() const { return p; } const T* end() const { return p + n; } ~container() { delete[] p; } T &operator[](size_t k) { return p[k]; } const T &operator[](size_t k) const { return p[k]; } void info() { std::cout << "Ilość elementów w tablicy: " << n << "\n"; // 直接遍历容器本身 for(const auto& c : *this) { std::cout << c << std::endl; } std::cout << "Typ danych: " << typeid(*p).name() << '\n'; } size_t length() const { return n; } }; int main(int argc, char** argv) { container<char> Z{'a', 'b', 'c', 'd'}; Z.info(); // 测试范围for循环 std::cout << "范围for循环遍历:\n"; for(const char& c : Z) { std::cout << c << " "; } std::cout << "\n"; // 测试const容器的遍历 const container<char> Z_const{'x', 'y', 'z'}; std::cout << "const容器遍历:\n"; for(const char& c : Z_const) { std::cout << c << " "; } std::cout << "\n"; return 0; }
关键修改点
- 将
begin和end改为无参成员函数,直接返回数组首地址p和末尾下一个地址p + n - 添加
const版本的begin和end,确保const容器也能被范围for循环遍历 - 删除无用的
getArray函数 - 修正
info函数里的遍历逻辑,改为遍历*this(容器对象本身) - 添加const版本的
operator[],保证const容器能通过下标访问元素
内容的提问来源于stack exchange,提问作者TyTu
相关产品推荐
相关产品推荐

