如何为自定义Matrix类实现接收范围的前向迭代器构造函数?
实现支持前向迭代器范围的Matrix构造函数
首先得说,你选前向迭代器真的很明智——它是迭代器概念里最通用的类型之一,只要是能做单遍向前遍历的迭代器(比如输入迭代器、双向迭代器、随机访问迭代器,甚至自定义的前向迭代器)都能适配,完美兼顾通用性和灵活性。
接下来咱们一步步实现这个构造函数:
核心思路
因为要兼容任意前向迭代器类型,咱们得把构造函数做成模板化的——毕竟前向迭代器不是一个具体的类,而是一组符合特定行为的类型的统称。构造函数需要接收三个参数:矩阵的阶数、范围的起始迭代器、范围的结束迭代器,然后把范围里的元素按顺序填充到方阵中。
完整代码实现
咱们把这个构造函数加到你给的Matrix类框架里:
#include <algorithm> #include <iterator> #include <vector> #include <stdexcept> // 用于抛出异常 using namespace std; template <class T> class Matrix { private: const size_t m_order; std::vector<std::vector<T>> m_data; public: // 支持前向迭代器范围的构造函数 template <typename ForwardIt> Matrix(size_t order, ForwardIt first, ForwardIt last) : m_order(order) { // 先校验元素总数是否和矩阵阶数匹配(n阶方阵需要n*n个元素) const size_t required_elements = order * order; const size_t actual_elements = std::distance(first, last); if (actual_elements != required_elements) { throw std::invalid_argument("Range size doesn't match matrix order"); } // 初始化二维vector的结构 m_data.resize(order, std::vector<T>(order)); // 遍历迭代器范围,填充矩阵元素 auto current = first; for (size_t i = 0; i < order; ++i) { for (size_t j = 0; j < order; ++j) { m_data[i][j] = *current++; } } } // 可以加个打印方法方便测试 void print() const { for (const auto& row : m_data) { for (const auto& elem : row) { std::cout << elem << " "; } std::cout << "\n"; } } };
关键细节说明
- 模板化构造函数:用
template <typename ForwardIt>来接收任意符合前向迭代器概念的类型,不管是std::vector的迭代器、数组指针,还是std::istream_iterator都能适配。 - 元素数量校验:用
std::distance计算迭代器范围的元素个数,虽然前向迭代器的distance是O(n)时间复杂度,但为了通用性这是必要的——如果是随机访问迭代器,编译器会自动优化成O(1)。 - 异常处理:当范围元素数量和矩阵阶数不匹配时,抛出
std::invalid_argument,避免构造出无效的矩阵。
使用示例
咱们来试试几种不同的迭代器类型:
1. 用std::vector的迭代器
#include <iostream> int main() { std::vector<int> values = {1,2,3,4,5,6,7,8,9}; Matrix<int> mat(3, values.begin(), values.end()); mat.print(); // 输出: // 1 2 3 // 4 5 6 // 7 8 9 return 0; }
2. 用普通数组的迭代器(指针)
int main() { double arr[] = {1.1, 2.2, 3.3, 4.4, 5.5, 6.6}; Matrix<double> mat(2, std::begin(arr), std::end(arr)); mat.print(); // 输出: // 1.1 2.2 // 3.3 4.4 return 0; }
3. 用输入迭代器(从标准输入读数据)
int main() { std::cout << "Enter 4 integers for 2x2 matrix:\n"; std::istream_iterator<int> input_it(std::cin), end_it; try { Matrix<int> mat(2, input_it, end_it); mat.print(); } catch (const std::invalid_argument& e) { std::cerr << "Error: " << e.what() << "\n"; } return 0; }
这样一来,你的Matrix类就能像STL算法那样,灵活接收各种范围输入啦~
内容的提问来源于stack exchange,提问作者Christopher Pisz
相关产品推荐
相关产品推荐

