Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Comportamento (per me) incomprensibile d'una funzione template
Forum - C/C++ - Comportamento (per me) incomprensibile d'una funzione template - Pagina 2

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 15:11
Sabato, 07/11/2015
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 il 07/11/2015 alle 15: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.
PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 17:09
Sabato, 07/11/2015
Testo quotato

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).

PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 699
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 8:05
Domenica, 08/11/2015
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 il 08/11/2015 alle 8: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.
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 19:37
Domenica, 08/11/2015
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.

PM Quote
Avatar
lumo (Member)
Expert


Messaggi: 449
Iscritto: 18/04/2010

Segnala al moderatore
Postato alle 22:19
Domenica, 08/11/2015
Testo quotato

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:
Codice sorgente - presumibilmente C++

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. template <class tipo> // prototipo della funzione template
  5. unsigned int CompattaArray(tipo *a, unsigned int totEl,
  6.         bool (*fNullita)(tipo*),
  7.         const tipo *nullo = NULL);
  8.  
  9. // prototipi delle funzioni di verifica
  10. // delle condizioni di nullita' (esempi)
  11. bool CondizioneNullitaPtr(char const **e);
  12. bool CondizioneNullitaDouble(double *e);
  13. bool CondizioneNullitaInt(int *e);
  14.  
  15. int main() {
  16.         const unsigned int totEl = 6;
  17.         unsigned int nElValidi = 0;
  18.  
  19.         // tutti i puntatori NULL vengono "cassati"
  20.         // gli elementi "residui" vengono annullati
  21.         const char * aPtr[totEl] = { "a","b",NULL,"c","d","e" };
  22.         const char * nPtr = NULL;
  23.         nElValidi = CompattaArray(aPtr, totEl, &CondizioneNullitaPtr, &nPtr);
  24.         for (unsigned int i = 0; i<totEl; ++i)
  25.                 printf("0x%08X\n", static_cast<unsigned int>(nPtr[i]));
  26.         printf("%u elementi validi\n\n", nElValidi);
  27.  
  28.         // tutti i valori inferiori a 0.5 vengono "cassati";
  29.         // gli elementi "residui" NON vengono annullati
  30.         double aDouble1[totEl] = { 1.0,0.5,0.0,0.49,2.76,0.54 };
  31.         nElValidi = CompattaArray(aDouble1, totEl, CondizioneNullitaDouble);
  32.         for (unsigned int i = 0; i<totEl; ++i)
  33.                 printf("%f  ", aDouble1[i]);
  34.         printf("\n%u elementi validi\n\n", nElValidi);
  35.  
  36.         // tutti i valori inferiori a 0.5 vengono "cassati";
  37.         // gli elementi "residui" vengono annullati
  38.         double aDouble2[totEl] = { 1.0,0.5,0.0,0.49,2.76,0.54 };
  39.         double nDouble = 0.0; // valore di annullamento double
  40.         nElValidi = CompattaArray(aDouble2, totEl, CondizioneNullitaDouble, &nDouble);
  41.         for (unsigned int i = 0; i<totEl; ++i)
  42.                 printf("%f  ", aDouble2[i]);
  43.         printf("\n%u elementi validi\n\n", nElValidi);
  44.  
  45.         // tutti i valori non compresi tra 5 e 10 vengono "cassati";
  46.         // gli elementi "residui" vengono annullati
  47.         int aInt[totEl] = { 1,6,8,-2,10,11 };
  48.         int nInt = 0; // valore di annullamento int
  49.         nElValidi = CompattaArray(aInt, totEl, CondizioneNullitaInt, &nInt);
  50.         for (unsigned int i = 0; i<totEl; ++i)
  51.                 printf("%d  ", aInt[i]);
  52.         printf("\n%u elementi validi\n\n", nElValidi);
  53.         getchar();
  54.         return 0;
  55. }
  56.  
  57. template <class tipo>
  58. unsigned int CompattaArray(tipo *a, unsigned int totEl,
  59.         bool (*fNullita)(tipo*),
  60.         const tipo *nullo) {
  61.         unsigned int i, j;
  62.  
  63.         for (i = j = 0; i<totEl; ++i)
  64.                 if (!fNullita(&a[i]))
  65.                         a[j++] = a[i];
  66.  
  67.         if (nullo)
  68.                 for (i = j; i<totEl; ++i)
  69.                         a[i] = *nullo;
  70.  
  71.         return j; // la quantita' degli elementi non nulli
  72.                           // "raggruppati" in testa all'array
  73. }
  74.  
  75. bool CondizioneNullitaPtr(char const **e) {
  76.         // CompattaArray() elimina tutti i puntatori NULL
  77.         return *e == NULL;
  78. }
  79.  
  80. bool CondizioneNullitaDouble(double *e) {
  81.         // CompattaArray() elimina tutti i valori inferiori a 0.5
  82.         return *e < 0.5;
  83. }
  84.  
  85. bool CondizioneNullitaInt(int *e) {
  86.         // CompattaArray() elimina tutti i valori non compresi tra 5 e 10
  87.         return *e < 5 || *e > 10;
  88. }



Prova a vedere

PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo