Zitat von
Ghostwalker:
Das heißt man hat die "Funktionalität" von Templates ohne den ganzen zusätzlichen Code, den ein Prä-Prozessor verzapft, und trotzdem die gewohnte pascalsche Typsicherheit
Ungefähr so. Dafür hast du einen gewissen Overhead zur Laufzeit.
Der Code-Bloat läßt sich auch bei Templates vermeiden, indem man Templates intern über typagnostische Klassen implementiert. Leider ist das für die STL nicht so einfach, da diese laut Standard (auch bezüglich der Allokatoren) eine gewaltige Flexibilität bieten muß.
Zitat von
OregonGhost:
Ob man das braucht, ist eine andere Frage
Zumindest ist es sehr nützlich. Vielleicht nicht gerade für numerische Berechnungen, aber ein praktisches Beispiel hatte ich weiter oben gepostet. Hier etwas ausführlicher:
Code:
template <typename T,
typename Base,
int direction = UCL_ITERWRAP_FORWARD,
typename iter = T*,
typename tag = std::bidirectional_iterator_tag> // only for derived classes
class BiDiIterator
: public std::iterator <tag, T>
{
typedef std::iterator <tag, T> _iterBase;
private:
struct _some_struct_t {};
public:
typedef typename IfThenElseType <TypesAreEqual <T, const T>::result,
BiDiIterator <const T, Base, direction, iter>,
_some_struct_t>::type
const_iterator_type;
typedef BiDiIterator iterator_type;
...
public:
BiDiIterator (const iterator_type& rhs) : _ptr (rhs._ptr) {}
BiDiIterator (const const_iterator_type& rhs) : _ptr (rhs._getWrappedIterator ()) {}
...
};
Das stammt aus meiner Implementation eines Iterator-Wrappers, der, abhängig davon, ob
value_type bereits
const ist, sowohl als
iterator als auch als
const_iterator genutzt werden kann. Allerdings muß ein
iterator sowohl aus
iterator- als auch aus
const_iterator-Objekten konstruierbar sein - und wenn der Iterator dann schon ein
const_iterator ist, gibts den Kopierkonstruktor zweimal. Um das zu vermeiden, nimmt der zweite Konstruktor, je nachdem, ob
value_type das gleiche wie
const value_type ist, entweder einen
const_iterator oder eine nichtöffentliche Struktur entgegen.
Weiter kann der Iterator über einen Template-Parameter entweder als (forward-)
iterator oder
reverse_iterator eingesetzt werden. Auch verwendet er je nachdem, ob der Iteratortyp, den er wrappt, einfach nur ein Zeiger auf den
value_type (der immer vorwärts iteriert) oder ein echter
reverse_iterator ist, dessen Inkrement- oder Dekrementoperator.
Mach das mal ohne TMP