autismo schrieb:
Zur Implementierung: Ich bin mir auch über die Implikation im Klaren, dass die Größe einer Klasse davon abhängt, wie ihre Methoden (und die, der abgeleiteten Klassen) instantiiert werden, wobei ich auf die Schnelle kein Problem damit sehe.
Weiss nicht was du mit "Grösse einer Klasse" meinst. Die grösse der Objekte der Klasse hängt auf jeden Fall nicht davon ab, sondern nur davon ob es überhaupt virtuelle Funktionen gibt oder eben gar keine.
autismo schrieb:
Wieso gibt es das nicht bereits?
Also erstmal wäre es denke ich relativ kompliziert und aufwendig zu implementieren.
Dabei müsste erstmal das ganze Programm (d.h. sämtliche Translation Units!) "compiliert" werden (evtl. ohne Code-Generierung), um festzustellen welche Instanzierungen von virtuellen Funktionstemplates benötigt werden. Dann müssten diese instanziert werden. Dabei können weitere Instanzierungen von virtuellen Funktionstemplates dazukommen, d.h. man müsste so lange loopen bis die "Queue" der benötigten Instanzierungen leer ist.
Erst danach weiss man welche VTable-Slots überhaupt benötigt werden und kann dann mit der Code-Generierung anfangen, bzw. damit die ganzen Vtable-Indexe in den generierten Code "hineinzupatchen".
Nebenbei erfordert das auch ein Feature das in C++98 vorhanden war, und dann, weil es bis auf einen Compiler (Comeau C++) keiner implementiert hatte, im 2011er Standard wieder entfernt wurde. Nämlich "Exported Templates".
autismo schrieb:
Und wie soll man das Problem mit filter_base zufriedenstellend lösen, ohne dass besagtes Sprachmittel zur Verfügung steht?
Indem man das, was du vollautomatisch haben willst, halbautomatisch macht:
struct filter_base
{
virtual ~filter_base() = default;
virtual void apply( matrix_24bit_rgb& ) const = 0;
virtual void apply( matrix_flt_rgb& ) const = 0;
};
template <class T>
struct template_filter_impl : public T
{
virtual void apply( matrix_24bit_rgb& mat ) const
{
T::apply_impl(mat);
}
virtual void apply( matrix_flt_rgb& mat ) const
{
T::apply_impl(mat);
}
};
struct darken_impl : public filter_base
{
template <class MAT>
void apply_impl( MAT& mat ) const
{
for( auto& i : mat )
i /= 2;
}
};
struct darken : public template_filter_impl<darken_impl>
{
};
Theoretisch kannst du hier auch das CRTP verwenden, dann könntest du dir die "Zwischenklassen" ( darken_impl & Co) sparen:
struct filter_base
{
virtual ~filter_base() = default;
virtual void apply( matrix_24bit_rgb& ) const = 0;
virtual void apply( matrix_flt_rgb& ) const = 0;
};
template <class T>
struct template_filter_base : public filter_base
{
virtual void apply( matrix_24bit_rgb& mat ) const
{
static_cast<T const*>(this)->apply_impl(mat);
}
virtual void apply( matrix_flt_rgb& mat ) const
{
static_cast<T const*>(this)->apply_impl(mat);
}
};
struct darken : template_filter_base<darken>
{
template <class MAT>
void apply_impl( MAT& mat ) const
{
for( auto& i : mat )
i /= 2;
}
};