Postato originariamente da AldoBaldo:
Vedo, hai trasformato const char * in char**. Capisco il perché della doppia indirezione, però non capisco come mai "const" è di troppo, visto che il compilatore non mi segnala errore per la sua presenza.
Mi puoi brevemente dove sta l'inghippo, così aggiungo al mio armamentario anche quella nozione?
EDIT: successivamente ho provato a togliere il "const", e il compilatore ha sputato fuori questa sfilza di eccezioni...
||=== Build: Release in Prova fTemplate (compiler: GNU GCC Compiler) ===|
[...]\main.cpp||In function 'int main()':|
[...]\main.cpp|35|error: no matching function for call to 'CompattaArray(const char* [6], const unsigned int&, bool (&
(char**), const char**)'|
[...]\main.cpp|35|note: candidate is:|
[...]\main.cpp|5|note: template<class tipo> unsigned int CompattaArray(tipo*, unsigned int, bool (*)(tipo*), const tipo*)|
[...]\main.cpp|5|note: template argument deduction/substitution failed:|
[...]\main.cpp|35|note: deduced conflicting types for parameter 'tipo' ('const char*' and 'char*')|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|
Dunque parrebbe che "const" sia necessario. Che casino! Forse perché sto effettivamente passando puntatori ricavati da un array di costanti stringa e non da un array di stringhe collocate in vettori di char...
In effetti mi sto incasinando pure io, comunque questa dovrebbe essere la versione pedante con tutti i const:
#include <stdio.h>
#include <string.h>
template <class tipo> // prototipo della funzione template
unsigned int CompattaArray(tipo *a, unsigned int totEl,
bool (*fNullita)(tipo*),
const tipo *nullo = NULL);
// prototipi delle funzioni di verifica
// delle condizioni di nullita' (esempi)
bool CondizioneNullitaPtr(char const **e);
bool CondizioneNullitaDouble(double *e);
bool CondizioneNullitaInt(int *e);
int main() {
const unsigned int totEl = 6;
unsigned int nElValidi = 0;
// tutti i puntatori NULL vengono "cassati"
// gli elementi "residui" vengono annullati
const char * aPtr[totEl] = { "a","b",NULL,"c","d","e" };
const char * nPtr = NULL;
nElValidi = CompattaArray(aPtr, totEl, &CondizioneNullitaPtr, &nPtr);
for (unsigned int i = 0; i<totEl; ++i)
printf("0x%08X\n", static_cast<unsigned int>(nPtr[i]));
printf("%u elementi validi\n\n", nElValidi);
// tutti i valori inferiori a 0.5 vengono "cassati";
// gli elementi "residui" NON vengono annullati
double aDouble1[totEl] = { 1.0,0.5,0.0,0.49,2.76,0.54 };
nElValidi = CompattaArray(aDouble1, totEl, CondizioneNullitaDouble);
for (unsigned int i = 0; i<totEl; ++i)
printf("%f ", aDouble1[i]);
printf("\n%u elementi validi\n\n", nElValidi);
// tutti i valori inferiori a 0.5 vengono "cassati";
// gli elementi "residui" vengono annullati
double aDouble2[totEl] = { 1.0,0.5,0.0,0.49,2.76,0.54 };
double nDouble = 0.0; // valore di annullamento double
nElValidi = CompattaArray(aDouble2, totEl, CondizioneNullitaDouble, &nDouble);
for (unsigned int i = 0; i<totEl; ++i)
printf("%f ", aDouble2[i]);
printf("\n%u elementi validi\n\n", nElValidi);
// tutti i valori non compresi tra 5 e 10 vengono "cassati";
// gli elementi "residui" vengono annullati
int aInt[totEl] = { 1,6,8,-2,10,11 };
int nInt = 0; // valore di annullamento int
nElValidi = CompattaArray(aInt, totEl, CondizioneNullitaInt, &nInt);
for (unsigned int i = 0; i<totEl; ++i)
printf("%d ", aInt[i]);
printf("\n%u elementi validi\n\n", nElValidi);
getchar();
return 0;
}
template <class tipo>
unsigned int CompattaArray(tipo *a, unsigned int totEl,
bool (*fNullita)(tipo*),
const tipo *nullo) {
unsigned int i, j;
for (i = j = 0; i<totEl; ++i)
if (!fNullita(&a[i]))
a[j++] = a[i];
if (nullo)
for (i = j; i<totEl; ++i)
a[i] = *nullo;
return j; // la quantita' degli elementi non nulli
// "raggruppati" in testa all'array
}
bool CondizioneNullitaPtr(char const **e) {
// CompattaArray() elimina tutti i puntatori NULL
return *e == NULL;
}
bool CondizioneNullitaDouble(double *e) {
// CompattaArray() elimina tutti i valori inferiori a 0.5
return *e < 0.5;
}
bool CondizioneNullitaInt(int *e) {
// CompattaArray() elimina tutti i valori non compresi tra 5 e 10
return *e < 5 || *e > 10;
}
Prova a vedere