2012-04-04 66 views
1

有沒有辦法在編譯時決定兩個運行時代碼路徑之一?我知道函數重載可以用來完成這個壯舉,但是隨着代碼大小的增加,我的兩個函數都被編譯並鏈接到程序中。有沒有辦法避免這種大小的開銷?C++編譯時條件運行時語句

從本質上講,我想要做的是:

#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; 
}; 

但現在,二make_copy成員函數編譯和鏈接到程序,即使X可能只能用抽象類模板參數實例化,在這種情況下,只需要其中的一個。

+0

優化器不會刪除未調用的函數嗎? – Nick 2012-04-04 13:00:45

+2

讓我清楚地說明一點:您擔心最終可執行文件中的單行函數的額外成本? – 2012-04-04 13:01:35

+0

另請注意,您在代碼中做了很多假設,例如,非抽象類型的每個對象都是完整的對象。即如果您有一種擴展了不同非抽象類型的類型,並且在中間類型上調用該函數,則您將進行分片。你的界面似乎提供了*將在每種情況下做到最好*承諾(複製/克隆),但是並不總是實現承諾。 – 2012-04-04 13:07:09

回答

3

從您的示例中,它看起來像函數是類 模板的成員。如果是這樣,他們只會被實例化,如果他們實際上使用 ;如果重載解析總是選擇其中一個,那麼其他的將永遠不會被實例化。

這是許多元編程技術的關鍵規則。它是 在這種情況下並不少見,如果未實例化的函數在實例化時會導致編譯時錯誤。