L'uso così pervasivo dei template ha alcuni importanti drawback:
  • il template finisce con l'"infettare" tutto il codice; se foo e bar devono a loro volta passare stream in giro, anche le altre funzioni dovranno essere template;
  • il codice deve essere tutto inline e in header, il che rallenta sensibilmente i tempi di parsing e compilazione;
  • sempre sui tempi di compilazione, espandere i template non è gratis; inoltre, ogni cambiamento nella classe passata come argomento comporta la ricompilazione di tutto l'ambaradam;
  • un template non specifica un contratto di interfaccia in alcuna maniera - se sbagli qualcosa esplode tutto con messaggi illeggibili;
  • inoltre, un template verifica solo quello che viene effettivamente usato, e non l'interfaccia richiesta "ufficialmente"; magari in questo rilascio della libreria non uso tutti i metodi dell'interfaccia, ma li ho preventivati perché nella prossima versione mi servono. Con un'interfaccia "stile OOP" i client della libreria sono obbligati a fare le cose correttamente da subito, mentre con un template si rompe tutto inaspettatamente solo quando inizio ad usare la nuova versione della libreria.


Inoltre, l'overhead del metodo virtuale spesso è risibile; in genere, conta solo se il metodo è estremamente breve nella misura in cui impedisce l'inlining (la doppia indirezione sarebbe costosa solo in un tight loop, e lì il branch predictor impara rapidamente qual è l'indirizzo giusto a cui saltare); inoltre, in un contesto in cui il compilatore sappia provare il tipo su cui foo o bar operano (ad esempio se foo viene chiamata su una variabile locale di tipo definito) e il loro body è disponibile (o è attiva l'LTCG) è possibile che il body della funzione venga espanso in linea e con dispatch statico.

In sintesi: il passaggio a template in casi come questi in genere è un'ottimizzazione dubbia per le prestazioni, e una pessimizzazione marcata in termini di leggibilità, chiarezza del codice, "autodocumentazione" del contratto e comodità di build. Starei a pensarci solo dopo aver verificato tramite profiling che si tratta effettivamente di un collo di bottiglia del codice.