Gibt es eine Möglichkeit, zur Kompilierungszeit einen von zwei Laufzeitcodepfaden zu bestimmen? Ich bin mir bewusst, dass das Überladen von Funktionen verwendet werden kann, um dieses Kunststück zu erreichen, aber dann steigt die Code-Größe, weil beide meiner Funktionen kompiliert und in das Programm eingebunden sind. Gibt es eine Möglichkeit, diesen Overhead zu vermeiden?C++ Compile-Time Conditional-Laufzeitanweisungen
Wesentlichen, was ich tun möchte, ist:
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_abstract.hpp>
template <class T>
class X
{
public:
void copy_t(T &old_t)
{
//
// if T is abstract, (meaning that t is a pointer)
//
t = old_t.clone();
//
// else
//
t = old_t;
}
private:
typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};
Der einzige Weg, ich weiß, geht überladenen Member-Funktionen:
template <class T>
class X
{
public:
void copy_t(T &old_t)
{
t = make_copy(old_t, t);
}
private:
T *make_copy(T &old_t, T *t)
{
return old_t.clone();
}
T &make_copy(T &old_t, T &t)
{
return old_t;
}
typename boost::mpl::if_<boost::is_abstract<T>, T *, T>::type t;
};
Aber jetzt, zwei make_copy
Mitgliederfunktionen zusammengestellt und in die verlinkte Programm, obwohl X
immer nur mit einem abstrakten Klassenvorlagenparameter instanziiert werden kann, in welchem Fall nur einer von ihnen benötigt wird.
Wird der Optimierer die nicht aufgerufenen Funktionen nicht entfernen? – Nick
Lassen Sie mich das klarstellen: Sie sind besorgt über die zusätzlichen Kosten einer Einzeiler-Funktion in Ihrer endgültigen ausführbaren Datei? –
Beachten Sie auch, dass Sie einige Annahmen im Code treffen, z. B. sind alle Objekte eines nicht abstrakten Typs ein vollständiges Objekt. I.e. Wenn Sie einen Typ haben, der einen anderen nicht abstrakten Typ erweitert, und die Funktion für den Zwischentyp aufgerufen wird, werden Sie geschnitten. Ihre Schnittstelle scheint das * zu bieten, was in jedem Fall das Beste ist * Versprechen (entweder kopieren/klonen), liefert dann aber nicht immer das Versprechen. –