我有一个Matrix模板类,我需要一个函数来设置具有可变数量的args的元素。
我应该可以这样称呼它:
aghMatrix<string> matrix;
matrix.setItems(2, 3, "torzmiae", "jestdnaci", "tablickore", "wyrazobed", "oelmntai", "rozmiaecy");
第一个整数是行数,第二个是列,其余(R * C)参数是我应该放入矩阵的元素。
它应该适用于任何数据类型,而不仅仅是原始类型。
目前,我的功能如下:
template<typename T>
template<typename... ARGS>
void aghMatrix<T>::setItems(const int rows, const int cols, ARGS... args) {
array<T, sizeof...(args)>unpacked_args {args...};
int row = 0;
int col = 0;
for (T arg : unpacked_args)
{
this->matrixPtr[row][col] = arg;
col++;
if (col == this->cols) {
row++;
col = 0;
}
}
return;
}
我假设我的矩阵对象能够容纳所有元素。它确实编译了许多关于将所有内容都转换为unsigned int的警告,但程序无论如何都不起作用(它在启动时冻结)。
template<typename T>
class aghMatrix {
public:
[...]
template<typename... ARGS> void setItems(const int rows, const int cols, ARGS... args);
[...]
private:
T **matrixPtr;
int rows;
int cols;
void createMatrix(const int row, const int col);
bool checkRowCol(const int row, const int col) const;
};
答案 0 :(得分:1)
编辑: 哎呀!我只是注意到你说过#34;非递归,&#34;所以我认为以下模式并不适合你。我现在仍然把它挂在这里,但我在下面提供了一个非递归解决方案(基于def make_all_pairs(list_):
pivot = list_.pop(0)
for el in list_:
pair = (pivot, el)
yield pair
if len(list_) > 1:
for pair in make_all_pairs(list_):
yield pair
x = make_all_pairs(["a","b","c","d","e"])
for el in x:
print el
,因此仅适用于POD类型)
如果我理解你想做什么,那么你可能想要递归的variadic参数解包模式;这样的事情似乎可以解决问题...
va_list
通常,您希望尽可能避免直接操作内存。除非你绝对需要它(也与直接记忆操作联系在一起),也要尽可能地避免任何施法巫术。
无论如何,使用#include <iostream>
using namespace std;
// Helper for build_matrix, taking zero variadic arguments.
// This serves as the termination in the recursive unpacking of the args.
template<typename T>
void build_matrix_helper(T**, size_t, size_t, size_t, size_t) { return; }
// Helper for build_matrix, taking at least one variadic argument.
template <typename T, typename ...ARGS>
void build_matrix_helper(T** matrix, size_t curr_row, size_t curr_col,
size_t row, size_t col, const T& first, ARGS...rest) {
if (curr_col < col) {
matrix[curr_row][curr_col] = first;
++curr_col;
return build_matrix_helper<T>(matrix, curr_row, curr_col, row, col, rest...);
}
else {
++curr_row;
curr_col = 0;
return build_matrix_helper<T>(matrix, curr_row, curr_col, row, col, first, rest...);
}
return;
}
// Bare bones implementation.
template<typename T, typename ...ARGS>
T **build_matrix(size_t row, size_t col, ARGS...elements) {
T **new_mat = new T*[row];
for (size_t j = 0; j < row; ++j)
new_mat[j] = new T[col];
build_matrix_helper<T>(new_mat, 0, 0, row, col, elements...);
return new_mat;
}
int main() {
int **nm = build_matrix<int>(2, 3, 1, 2, 3, 4, 5, 6);
for (size_t i = 0; i < 2; ++i) {
cout << "[" << i + 1 << "]: ";
for (size_t j = 0; j < 3; ++j)
cout << nm[i][j] << " ";
cout << endl;
}
delete[] nm;
return 0;
}
可以使用下面的非递归解决方案。
注意 由于这使用了std::va_list
,因此它不适用于非POD类型。
va_list
编辑 初始化列表
正如您对OP的评论中所建议的那样,最好使用初始化列表。我知道这不是你原来要求的,但也许值得考虑:
#include <iostream>
#include <cstdarg>
using namespace std;
template <typename T>
T **build_matrix(size_t row, size_t col, ...) {
va_list args;
T **matrix = new T*[row];
va_start(args, col);
for (size_t i = 0; i < row; ++i) {
matrix[i] = new T[col];
for (size_t j = 0; j < col; ++j)
matrix[i][j] = va_arg(args, T);
}
va_end(args);
return matrix;
}
int main() {
int **nm = build_matrix<int>(2, 3, 1, 2, 3, 4, 5, 6);
for (size_t i = 0; i < 2; ++i) {
cout << "[" << i + 1 << "]: ";
for (size_t j = 0; j < 3; ++j)
cout << nm[i][j] << " ";
cout << endl;
}
delete[] nm;
return 0;
}