C++ 以范围作为参数
许多STL算法都有一个范围和一个参数。我感兴趣的是看看在我的构造函数中获取一个范围需要什么 假设我正在创建一个矩阵类。构造函数是什么样子的? 我相信前向迭代器是最通用的C++ 以范围作为参数,c++,C++,许多STL算法都有一个范围和一个参数。我感兴趣的是看看在我的构造函数中获取一个范围需要什么 假设我正在创建一个矩阵类。构造函数是什么样子的? 我相信前向迭代器是最通用的 #include <algorithm> #include <iterator> #include <vector> using namespace std; template <class T> class Matrix { private: const size_
#include <algorithm>
#include <iterator>
#include <vector>
using namespace std;
template <class T>
class Matrix
{
private:
const size_t m_order;
std::vector<std::vector<T>> m_data;
public:
Matrix(const size_t order, forward_iterator_tag begin, forward_iterator_tag end)
:
m_order(order)
, m_data (order, std::vector<T>(order))
{
if (std::distance(begin, end) != order * order)
{
throw std::runtime_error("invalid params");
}
for (size_t currentRow = 0; currentRow < m_order; ++currentRow)
{
for (size_t currentColumn = 0; currentColumn < m_order; ++currentColumn)
{
m_data[row].push_back(*begin);
if (++begin == end)
{
throw std::runtime_error("invalid params");
}
}
}
}
T GetElement(size_t row, size_t column) const
{
if (row > order || column > order)
{
throw std::runtime_error("invalid params");
}
return m_data[row][column];
}
};
//------------------------------------------------------------------------------
// Finds all permutations of the distinct numbers that make up a matrix of order n, from 1 to n^2
std::vector<std::vector<size_t>> GetAllPermutations(size_t order)
{
std::vector<std::vector<size_t>> result;
// It is important than we have these sorted least to greatest to start, in order to use the next_permutation algorithm
std::vector<size_t> elements;
for(size_t currentNumber = 1; currentNumber <= order * order; ++currentNumber)
{
elements.push_back(currentNumber);
}
do
{
// Store the current permutation
result.push_back(elements);
} while (std::next_permutation(elements.begin(), elements.end()));
return result;
}
int main()
{
const size_t order = 3;
std::vector<std::vector<size_t>> permutations = GetAllPermutations(order);
Matrix<size_t> matrix(order, permutations.begin(), permutations.end());
return 0;
}
#包括
#包括
#包括
使用名称空间std;
模板
类矩阵
{
私人:
const size\u t m\u order;
std::向量m_数据;
公众:
矩阵(常量大小顺序、前向迭代器标记开始、前向迭代器标记结束)
:
m_订单(订单)
,m_数据(顺序,标准::向量(顺序))
{
如果(标准::距离(开始、结束)!=订单*订单)
{
抛出std::runtime_错误(“无效参数”);
}
对于(大小\u t currentRow=0;currentRow顺序| |列>顺序)
{
抛出std::runtime_错误(“无效参数”);
}
返回m_数据[行][列];
}
};
//------------------------------------------------------------------------------
//查找构成n阶矩阵(从1到n^2)的不同数字的所有排列
std::vector GetAllPermutations(大小顺序)
{
std::向量结果;
//为了使用下一个排列算法,我们必须从最小到最大的顺序开始
std::向量元素;
对于(size\t currentNumber=1;currentNumber,您将构造函数的迭代器参数声明为std::forward\u iterator\u标记
,它是一个而不是实际的迭代器
迭代器标记用于将模板专门化限制为特定类型的迭代器
例如,假设一个算法需要随机访问迭代器,如果将非随机访问迭代器传递给它,它可能会产生编译器错误
或者,给定算法的多个重载可以使用迭代器标记来限制它们接受的迭代器类型,因此当传递不同类型的迭代器时,它们可以使用不同的逻辑/优化
在您的情况下,要执行您想要的操作,您需要更改构造函数,使其具有迭代器类型的模板参数(就像STL算法一样):
仅当InputIt
是迭代器类型,其std::iterator\u traits
专门化提供了一个iterator\u类别
,即std::forward\u iterator\u标记
或其后代时,代码才会编译
这种方法通常称为。您将构造函数的迭代器参数声明为std::forward\u iterator\u tag
的实例,它是一个而不是实际的迭代器
迭代器标记用于将模板专门化限制为特定类型的迭代器
例如,假设一个算法需要随机访问迭代器,如果将非随机访问迭代器传递给它,它可能会产生编译器错误
或者,给定算法的多个重载可以使用迭代器标记来限制它们接受的迭代器类型,因此当传递不同类型的迭代器时,它们可以使用不同的逻辑/优化
在您的情况下,要执行您想要的操作,您需要更改构造函数,使其具有迭代器类型的模板参数(就像STL算法一样):
仅当InputIt
是迭代器类型,其std::iterator\u traits
专门化提供了一个iterator\u类别
,即std::forward\u iterator\u标记
或其后代时,代码才会编译
这种方法通常被称为。前向迭代器\u标记
是一个标记。您将无法从该参数初始化迭代器
迭代器可以是指针、类、整数——基本上是满足条件的任何对象。显然,在一般情况下,您无法预测将传递的迭代器的类型,这就是为什么通常让函数使用模板推断迭代器的原因
template<class InputIt>
void foo(InputIt begin, InputIt end);
模板
void foo(输入开始,输入结束);
这样,您就不需要知道迭代器的类型,并且可以以统一的方式处理所有可能的迭代器类型。forward\u iterator\u tag
是一个标记。您将无法从该参数初始化迭代器
迭代器可以是指针、类、整数——基本上是满足条件的任何对象。显然,在一般情况下,您无法预测将传递的迭代器的类型,这就是为什么通常让函数使用模板推断迭代器的原因
template<class InputIt>
void foo(InputIt begin, InputIt end);
模板
void foo(输入开始,输入结束);
这样,您就不需要知道迭代器的类型,并且可以以一种统一的方式处理所有可能的迭代器类型。使用向量的向量让您的生活变得艰难。
你不需要它,它会导致内存碎片
template<class T>
class Matrix
{
private:
std::size_t m_order;
std::vector<T> m_data;
public:
template <class InputIterator>
Matrix(std::size_t order,
InputIterator begin, InputIterator end)
: m_order(order)
{
if (std::distance(begin, end) > order * order) {
throw std::runtime_error("invalid params");
}
m_data.reserve(order * order);
std::copy(begin, end, std::back_inserter(m_data));
m_data.resize(order * order);
}
T GetElement(size_t row, size_t column) const
{
checkIndexes(row, column);
return m_data[row + column * m_order];
}
void SetElement(size_t row, size_t column, T value)
{
checkIndexes(row, column);
m_data[row + column * m_order] = value;
}
private:
void checkIndexes(size_t row, size_t column) const {
if (row > order || column > order) {
throw std::runtime_error("invalid params");
}
}
… … …
模板
类矩阵
{
私人:
std::订单大小;
std::向量m_数据;
公众:
模板
矩阵(标准::尺寸和顺序,
输入计算器开始,输入计算器结束)
:m_订单(订单)
{
if(标准::距离(开始、结束)>顺序*顺序){
抛出std::runtime_错误(“无效参数”);
}
m_数据保留(订单*订单);
std::copy(开始、结束、std::back_插入器(m_数据));
m_数据。调整大小(顺序*顺序);
}
GetElement(大小行、大小列)常量
{
检查索引(行、列);
返回m_数据[行+列*m_顺序];
}
void SetElement(大小行、大小列、t值)
{
检查索引(行、列);
m_数据[行+列]
template<class T>
class Matrix
{
private:
std::size_t m_order;
std::vector<T> m_data;
public:
template <class InputIterator>
Matrix(std::size_t order,
InputIterator begin, InputIterator end)
: m_order(order)
{
if (std::distance(begin, end) > order * order) {
throw std::runtime_error("invalid params");
}
m_data.reserve(order * order);
std::copy(begin, end, std::back_inserter(m_data));
m_data.resize(order * order);
}
T GetElement(size_t row, size_t column) const
{
checkIndexes(row, column);
return m_data[row + column * m_order];
}
void SetElement(size_t row, size_t column, T value)
{
checkIndexes(row, column);
m_data[row + column * m_order] = value;
}
private:
void checkIndexes(size_t row, size_t column) const {
if (row > order || column > order) {
throw std::runtime_error("invalid params");
}
}
… … …