1

コンパイル時に、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つだけが必要です。

4

1 に答える 1

3

あなたの例から、関数はクラステンプレートのメンバーであるように見えます。その場合、実際に使用された場合にのみインスタンス化されます。過負荷解決が常にそれらの1つを選択する場合、もう1つはインスタンス化されません。

これは、多くのメタプログラミング手法にとって重要なルールです。このような場合、インスタンス化されていない関数がインスタンス化された場合にコンパイル時エラーが発生することは珍しくありません。

于 2012-04-04T13:00:46.810 に答える