Thanks to Bathsheba for the tips, I finally came up with solutions containing pointers to functions that I'm not sure about. The main problem is the creation of specific functions that may require additional parameters.
Note. Thanks to joop, we need an extra function call, which can be omitted with a macro solution.
For example, such a visitor resets all matrix elements with a given value. Another visitor may change items using a set of parameters or not even need one parameter. So basically I come across the question of flexible type definition of a vistor function.
BTW: in C ++, this can be solved either using std::bind or using templates .
Nested Functions:
Nested functions are an extension of GCC and, for example, are not available in Clang. However, here is a sample code:
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 ); }
Variadic functions:
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 pointer:
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 ); }
Maybe there are other ways, Iβm thinking about using static function variables to initialize the visitor function, also related to variational functions.
Thanks for your feedback.