コンパイル時に2つの実行時コードパスのいずれかを決定する方法はありますか?私は関数のオーバーロードがこの偉業を達成するために使用できることを認識していますが、私の関数の両方がコンパイルされ、プログラムにリンクされているのでコードサイズが大きくなります。このサイズのオーバーヘッドを避ける方法はありますか?コンパイル時の条件付き実行時文
基本的に、私は何をしたいです:
#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;
};
私が知っている唯一の方法は、必要とするオーバーロードされたメンバ関数:
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;
};
しかし、今、2つのmake_copy
メンバ関数は、にコンパイルとリンクされていますたとえX
が抽象クラステンプレートパラメータでインスタンス化されることがありますが、その場合はそのうちの1つだけが必要です。
オプティマイザは未コール関数を削除しませんか? – Nick
私はこれを明確にしましょう:最終実行ファイルの1ライナー関数の追加コストが心配ですか? –
また、コードではかなりの前提があることに注意してください。たとえば、非抽象型のすべてのオブジェクトは完全なオブジェクトです。私。異なった非抽象型を拡張する型があり、関数が中間型で呼び出された場合は、スライスします。あなたのインタフェースは、*お約束(コピー/クローンのいずれか)の場合に最善を尽くすものを提供するように見えますが、その後必ずしも約束を果たしているとは限りません。 –