Eh, perdonami tu per il ritardo ancora più clamoroso...Ti ringrazio per la panoramica d'uso, intanto anche dei nostri collaboratori lo stanno usando per loro progetti interni, vediamo come si evolve la cosa.
Meanwhile:
Due indovinelli (da bug veri che mi hanno fatto impazzire per giorni):
Dove sta il problema?codice:void someFunctionCallback(void * dummy) { std::stringstream ss; ss << atoi(((std::string)parms("max_vel")).c_str()) * 1000; some_object->setParameter("max_vx", ss.str()); some_object->setParameter("max_vy", ss.str()); ss << atoi(((std::string)parms("max_vel_inout")).c_str()) * 1000; some_object->setParameter("max_vx_inout", ss.str()); some_object->setParameter("max_vy_inout", ss.str()); }
Sintomi: "ogni tanto" nel caricamento di altri parametri del programma venivano o letti solo zeri, o valori assurdi (o meglio, il sintomo originario erano crash in parti assurde del programma, ma qui semplifichiamocodice:// reimposto il locale perche' se linko le QT // viene impostato il locale della macchina char * locale = setlocale(LC_ALL, NULL); setlocale(LC_ALL, "C"); FILE *mf=fopen(filename, "r"); // ... un bel po' di fscanf & co. ... if (mf) fclose(mf); setlocale(LC_ALL, locale);).
Dove sta il problema? (qui ce n'è più di uno in realtà)
Altri angoli oscuri del C++ che ho scoperto per caso in tempi recenti:
- le regole di scoping del C++ sono sempre più strane di quel che sembra:
IOW: lo scoping delle variabili introdotte a livello di condizione dell'if perdura anche negli else; non riesco a cogliere completamente l'utilità di questo fatto, ma prendo atto.codice:if(auto *derived_ptr = dynamic_cast<Derived *>(base_ptr)) { derived_ptr->doSomething(); } else { derived_ptr->doSomethingElse(); // <-- ho scritto derived_ptr per sbaglio, ma compila! (ovviamente crash) }Mi sembra quasi peggio delle list comprehension in Python, che "pisciano fuori" la variabile di iterazione nello scope di funzione.
- std::function non è reference counted, ma lavora per copia, per cui bisogna stare attenti a fare lambda che catturano per copia roba troppo grossa, visto che si tende a trattare la copia di std::function come copia di oggetti leggeri; non so perché, ma mi ero sempre immaginato che lavorasse per reference-counting;
- ho finalmente colto uno dei motivi per cui sto abusando di std::function: in un certo senso è un'incursione del duck typing in un linguaggio a tipizzazione statica - l'unica cosa che importa è che quello che passo abbia un'interfaccia compatibile a quella richiesta, senza menate di ereditarietà, gerarchie di classi e compagnia (e, rispetto all'uso tipico del C++, consente di mantenere un comportamento simil-polimorfico senza doversi esplicitamente portare in giro puntatori a roba allocata sullo heap); il fatto che, rispetto a linguaggi come Python, mantenga comunque un buon controllo a compile-time, rende la cosa particolarmente usabile. Mi chiedo se si riesce ad estendere in maniera sintatticamente comoda ad interfacce più complicate (rispetto alla singola funzione)