Oppure

Loading
07/11/15 14:05
AldoBaldo
Lumo, mi fai fare la figura del pirla, e me lo merito. A una funzione che accetta un puntatore a puntatore passo l'indirizzo a un puntatore "semplice" e manco me ne accorgo pur guardando, e riguardando, e riguardando ancora. Robe da chiodi. Prosciutto sugli occhi. Che vergogna! Be', me la cavo come al solito: facendo notare la firma in calce a ciascuno dei miei messaggi.

Ora funziona tutto a dovere.
Grazie davvero per la guida che mi offrite (tu e gli altri) nell'orientarmi in questo mio hobby.

P.S. Ero disperato, perché ormai avevo già finito la terza bottiglia di rosso... purtuttavia continuavo a non ricavarne nessuna illuminazione. :rotfl:
PP.SS. Non è vero, non mi sono pippato così tanto rosso... però dirlo fa tanto "colore"!
Ultima modifica effettuata da AldoBaldo 07/11/15 14:12
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
07/11/15 14:11
AldoBaldo
TheDarkJuster, ho fatto in modo che le funzioni CondizioneNullitaXxxx() ricevessero puntatori e non valori-copia perché ho pensato a situazioni nelle quali magari la funzione template CompattaArray() viene istanziata per trattare classi complesse con un nutrito impiego di memoria dinamica. Così facendo, nelle mie intenzioni, volevo evitare d'attivare il costruttore di copia e saltare così un sacco di passaggi potenzialmente inutili. E' ben vero che poi vanifico il tutto con quella serie infinita di operatori di assegnamento in CompattaArray(), ma la mia tecnica è limitata e più in là di così non sono riuscito ad andare. Non ancora, per lo meno. (la speranza è l'ultima a morire)
Ultima modifica effettuata da AldoBaldo 07/11/15 14:13
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
07/11/15 16:09
lumo
Postato originariamente da AldoBaldo:

Lumo, mi fai fare la figura del pirla, e me lo merito. A una funzione che accetta un puntatore a puntatore passo l'indirizzo a un puntatore "semplice" e manco me ne accorgo pur guardando, e riguardando, e riguardando ancora. Robe da chiodi. Prosciutto sugli occhi. Che vergogna! Be', me la cavo come al solito: facendo notare la firma in calce a ciascuno dei miei messaggi.

Ora funziona tutto a dovere.
Grazie davvero per la guida che mi offrite (tu e gli altri) nell'orientarmi in questo mio hobby.

P.S. Ero disperato, perché ormai avevo già finito la terza bottiglia di rosso... purtuttavia continuavo a non ricavarne nessuna illuminazione. :rotfl:
PP.SS. Non è vero, non mi sono pippato così tanto rosso... però dirlo fa tanto "colore"!


Un puntatore sfugge a tutti, attenzione però, l'errore principale era la constness negli argomenti che passavi. Avevi messo un const di troppo (se guardi riga per riga trovi la modifica).
aaa
08/11/15 7:05
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...
Ultima modifica effettuata da AldoBaldo 08/11/15 7:09
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
08/11/15 18:37
Roby94
Sembra che tu cerchi di invocare una funzione con primo paramento un puntatore a costante char, perché usi const? c'è un motivo preciso? E quello che cercavo di capire dal primo post. Credo che l'errore stia nel fatto che const non è di per se un tipo e tu stai richiedendo al templeate di consideralo tale.
aaa
08/11/15 21:19
lumo
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
aaa