Newsgroup: it.comp.lang.c++
Titolo: Signor Stroustrup, sono molto deluso...

... e le spiego perchè. Durante i miei ripetuti abusi della fantastica 
(ma mal disegnata) funzionalità dei template ho incontrato un problema 
estremamente fastidioso. Immaginiamo di avere una classe parser pensata 
per il polimorfismo statico:
/*
    NOTA! per semplicità è stato omesso il codice che sostituisce
    static_cast con una variante sensata che non controlla istericamente
    ogni puntatore a classe se è NULL o no (rovinando l'ottimizzazione)!
*/
template<typename EventImpl> class MooParser
{
protected:
    // Implementazione di default
    void onSyntaxErrorImpl() { }
    // "Thunk" che toglie la type-safety
    void onSyntaxErrorImpl(MooParser<EventImpl>&)
    { static_cast<EventImpl *>(this)->onSyntaxErrorImpl(); }
public:
    template<class InIter> InIter parse(InIter begin, InIter end)
    {
       EventImpl * outerThis = static_cast<EventImpl *>(this);
       InIter cur = begin;
       static const char moo[] = { 'M', 'O', 'O' };
       /*
          Già che ci siamo, sig. Stroustrup, quand'è che questo sarà
          parte del linguaggio o della libreria standard?
       */
       static const size_t mooLen = sizeof(moo) / sizeof(moo[0]);
       for(size_t i = 0; i < mooLen && cur != end; ++ cur, ++ i)
       {
          if(*cur != moo[i])
          {
             outerThis->onSyntaxErrorImpl(*this);
             break;
          }
       }
       return cur;
    }
};
L'idea è che vada usata derivando da essa:
class MyMooParser: public MooParser<MyMooParser>
{
};
Implementando tutte le funzioni di gestione eventi che riteniamo opportuno:
class MyMooParser: public MooParser<MyMooParser>
{
    friend MooParser<MyMooParser>;
    void onSyntaxErrorImpl()
    {
       EndOfTheWorld();
    }
};
Niente funzioni virtuali, niente puntatori a funzione membro, efficienza 
assoluta perchè tutto il codice viene generato inline. Come scrivere un 
parser ad-hoc, solo che è riusabile!
Avrà anche notato questa bizzarrìa:
             outerThis->onSyntaxErrorImpl(*this);
La classe passa se stessa come parametro "inutile" allo scopo di 
riportare un po' di ordine e type safety nel "Far West" dei template. In 
questo modo una classe che deriva da più di una classe "policy" può fare 
affidamento (se lo desidera! altrimenti c'è il "thunk") su una garanzia 
più forte del semplice "colpo di fortuna" dell'unicità dei nomi delle 
funzioni membro da reimplementare
Ma è proprio qui che, per usare un'espressione colorita del mio paese, 
"casca l'asino". Quello che succede, in realtà, è che la solitaria 
(re)definizione di onSyntaxErrorImpl in MyMooParser nasconde non solo la 
precedente definizione con la stessa lista di argomenti, ma anche tutti 
i suoi overload! anche quelli chiaramente non ambigui!
Che assurdità!
Per cui la compilazione di questa riga:
             outerThis->onSyntaxErrorImpl(*this);
fallisce con il compilatore che, come un proverbiale asino, si 
incaponisce sostenendo che onSyntaxErrorImpl non accetta nessun 
argomento, anzichè uno! perchè l'unica definizione sopravvissuta al 
"macello" è quella di MyMooParser, che con quell'unica, solitaria 
definizione ha "ucciso" potenzialmente una decina di altre!
A causa di questa (gratuita!) limitazione mi è impossibile portare a 
termine il mio lavoro. Spero degnerà il mio caso dell'attenzione che 
sicuramente merita!
Metaprogrammaticamente suo,
Il suo fan Numero Uno

 i suoi overload! anche quelli chiaramente non ambigui!
class MyMooParser: public MooParser<MyMooParser>
{
    friend class MooParser<MyMooParser>;
    using MooParser<MyMooParser>::onSyntaxErrorImpl;
    void onSyntaxErrorImpl()
    {
       EndOfTheWorld();
    }
};
ci cascano tutti i gnubbetti!
-- 
sbi

 ci cascano tutti i gnubbetti!
così ovvio! ortogonale! elegante! come fa uno a non arrivarci, senza un 
difetto cerebrale congenito!

 difetto cerebrale congenito!
leggendo il fottuto manuale ;)
-- 
sbi

post scriptum: dilemma: aggiungere altre trenta righe di commenti 
spiegando la contorsione, la perversione, la distorsione mentale 
ennesima, con schemino in ASCII art degli scope, e facilitare il lavoro 
al mio successore? o non farlo, garantirmi lavoro sicuro, ottenere fama 
e successo nel mondo mortale ma condannare la mia anima immortale a 
bruciare all'inferno per l'eternità?
Arduo!

 leggendo il fottuto manuale ;)
perchè mai fare uno sforzo inutile, cercando di mettermi nella perversa 
mente del suo autore per formulare la mia frase di ricerca nello stesso 
modo in cui il soggetto Lombrosiano l'ha messa per iscritto? quando 
posso andare "sull'Inter Net" con un nome falso, gonfiare l'ego di una 
persona con la metà dei miei anni che trova a mie spese la mia risposta 
in una mezzora durante la quale faccio altro? Il progresso!

 in una mezzora durante la quale faccio altro? Il progresso!
sento un fremito nell'abbozzo :)
-- 
sbi che perlomeno passa per giovane

 difetto cerebrale congenito!
Per arrivarci, avresti dovuto pensare a quali problemi si sarebbero 
avuti se il tuo codice avesse funzionato.
Kiuhnm

 sento un fremito nell'abbozzo :)
il soggetto Lombrosiano in questione è, ovviamente, il torvo autore del 
"manuale"... se un testo del genere esiste come oggetto di questo mondo 
e non di quello delle idee, per un linguaggio che non ha avuto una 
"specifica" fino al 1998! e che pure conta innumerevoli tentativi di... 
implementazione (tutti molto creativi, peraltro!)