Grazie a Bathsheba per dare suggerimenti, ho finalmente trovato soluzioni che prevedevano puntatori di funzione, di cui non sono sicuro. Il problema principale è la creazione di funzioni specifiche che potrebbero richiedere parametri aggiuntivi.
Nota: grazie a joop, è necessario quindi un richiamo di funzione aggiuntivo, che potrebbe essere omesso con una soluzione macro.
Ad esempio, un visitatore del genere reimposta tutti gli elementi della matrice con un determinato valore. Un altro visitatore potrebbe modificare gli elementi con un set di parametri o non avere nemmeno bisogno di un singolo parametro. Quindi fondamentalmente affronto la domanda su una definizione flessibile del tipo di funzione vistor.
BTW: in C++ questo può essere risolto con std::bind
o con templates
.
Funzioni nidificate:
funzioni nidificate sono un'estensione GCC, e ad esempio non disponibile con Clang.Tuttavia qui è il codice di esempio:
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);
}
Funzione Variadica:
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);
}
vuoto puntatore:
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);
}
Forse esistono altri modi, penso di usare funzione statica variabili per l'inizializzazione della funzione visitatore, che coinvolgono anche funzioni variadiche.
Grazie per il vostro feedback.
È possibile creare una macro che generi questi loop. – Crozin
Sì, è possibile utilizzare la funzione o la macro in questi casi. –
Una macro sarebbe probabilmente disordinata (non ovvia per il lettore) da chiamare o creerebbe "i" e 'j' vars fantasma (anche non ovvio per il lettore), Se crei i vars nascosti, anche loro non può essere annidato. – DaveRandom