ヒントを与えてくれたBathshebaのおかげで、私は最終的に私が自信を持っていない関数ポインタを含むソリューションを思いつきました。主な問題は、追加のパラメータが必要な特定の関数の作成です。
注:joopのおかげで、マクロソリューションでは省略可能な追加の関数呼び出しが必要になります。
たとえば、このような訪問者は、すべての行列要素を所定の値でリセットします。別の訪問者は、要素のセットをパラメータで変更したり、単一のパラメータを必要としない場合もあります。ですから、基本的には、vistor関数型の柔軟な定義に疑問があります。
BTW:C++では、これはstd::bind
またはtemplates
のいずれかで解決できます。
入れ子関数:
ネストされた関数は、GCCの拡張であり、例えばClangでは利用できません。それにもかかわらず、ここでのコードの例です:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) (double* element);
void visitMatrixElements(Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn) {
for(size_t i = 0; i < rows; ++i) {
for(size_t j = 0; j < cols; ++j){
fn(&m[i][j]);
}
}
}
void filM(Matrix m, size_t rows, size_t cols, double val) {
void fill(double *element) {
*element = val;
}
visitMatrixElements(m, rows, cols, fill);
}
可変引数機能:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) (double* element, va_list args);
void visitMatrixElements(Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn, ...) {
va_list args,copy;
va_start(args, fn);
for(size_t i = 0; i < rows; ++i) {
for(size_t j = 0; j < cols; ++j){
va_copy(copy, args);
fn(&m[i][j], copy);
va_end(copy);
}
}
va_end(args);
}
void fill(double *element, va_list args) {
*element = va_arg(args, double);
}
void filM(Matrix m, size_t rows, size_t cols, double val) {
visitMatrixElements(m, rows, cols, fill, val);
}
のvoidポインタ:
typedef double** Matrix;
typedef void (*MatrixElementVisitor) (double* element, void *args);
void visitMatrixElements(Matrix m, size_t rows, size_t cols, MatrixElementVisitor fn, void *args) {
if(m) {
for(size_t i = 0; i < rows; ++i) {
if(m[i]) {
for(size_t j = 0; j < cols; ++j){
fn(&m[i][j], args);
}
}
}
}
}
void fill(double* element, void *args) {
if(!args) {
return;
}
*element = *((double*)args);
}
void filM(Matrix m, size_t rows, size_t cols, double val) {
visitMatrixElements(m, rows, cols, fill, &val);
}
たぶん、他の方法が存在し、私は静的関数を使用して考えますバリアリ関数を含むビジター関数の初期化のための変数。
ご意見ありがとうございます。
これらのループを生成するマクロを作成することができます。 – Crozin
はい、この場合、関数またはマクロを使用できます。 –
隠されたvarsを作成した場合、マクロはおそらく乱雑で(読者にはわかりません)、隠れた 'i'と' j'varsを呼び出すか、作成します(読者には明白ではありません)。入れ子にできませんでした。 – DaveRandom