2013-05-29 50 views
5

在模板類中的函數中,我試圖區分基本類型和其他類型。C++:替代'std :: is_fundamental'?

在C++ 11,你可以這樣做:

if(std::is_fundamental<T>::value) 
{ 
    // Treat it as a primitive 
} 
else 
{ 
    //Treat it otherwise 
} 

請糾正我,如果我錯了,這是不是隻在C++ 11

是否有早期版本的C本的替代++ ?

回答

8

你可以在C++ 03這樣的使用Boost's type traits

#include <boost/type_traits/is_fundamental.hpp> 

... 

if(boost::is_fundamental<T>::value) 
{ 
    // Treat it as a primitive 
} 
else 
{ 
    //Treat it otherwise 
} 

我想這應該對C++ 98正常工作。

+0

謝謝。 「include」爲+1。 – Subway

2

有了這段代碼,你會遇到麻煩。如果您需要區分不同的類型特徵,則必須在編譯時完成,而不是在運行時完成。根據您執行的操作,if的兩個分支之一可能無法編譯。所以最好轉發到一個專門的功能:

void operation_impl(boost::true_type /*other params*/) { 
    // Treat it is primitive 
} 

void operation_impl(boost::false_type /*other params*/) { 
    // Treat it otherwise 
} 

template<class T> 
void operation(/* params*/) { 
    operation_impl(boost::is_fundamental<T>::type() /*other params*/); 
} 

在這種實現技術只有使用的分支需要編譯(即是正確的)。

編輯:

這裏有一些額外的信息。解決這個問題的辦法與模板的實例有關。我從is_fundamental切換到is_array以顯示操作如何失敗。

讓我們開始第一個例子:

template <class T> 
void fun(T t) { 
    if(boost::is_array<T>::value) 
    { 
     std::cout << "true" << std::endl; 
    } 
    else 
    { 
     std::cout << "false" << std::endl; 
    } 
} 

void f(int i) { 
    fun(i); 
} 

它將編譯和運行,編譯器會看到只有一個if語句的分支將被使用,並刪除其他爲未使用的代碼。

在我的第二個例子,我會盡我在使用一個數組操作的情況下someithing:

template<class T> 
void fun(T& t) { 
    if(boost::is_array<T>::value) 
    { 
     std::cout << t[0]; 
    } 
    else 
    { 
     std::cout << t; 
    } 
} 

void f(int i) { 
    fun(i); 
} 

現在,它不會編譯。原因是int作爲模板參數t[0]生病了。您不能使用此運行時語句來區分代碼中所需的編譯時類型屬性(在本例中爲數組的使用屬性以及使用t[0])。

在第三示例中,我們將通過函數重載上編譯時disitinguish:

template<class T> 
void fun_impl(boost::true_type, T& t) { 
    std::cout << t[0]; 
} 

template<class T> 
void fun_impl(boost::false_type, T& t) { 
    std::cout << t; 
} 

template<class T> 
void fun(T& t) { 
    fun_impl(typename boost::is_array<T>::type(),t); 
} 

void f(int i) { 
    fun(i); 
} 

這裏is_array<T>::type要麼true_typefalse_type。該結果用作選擇器,用於在編譯時選擇fun_impl的正確過載,並且只對所選擇的過載進行實例化和編譯。

通常這種技術被用來在互聯網時間選擇一個最佳的實現,如果這些類型具有某些屬性,那麼這個實現可能只是可編譯的。

2日編輯:

當然這個變化的意願,如果static if是語言的一部分。

+0

可否請您詳細說明我可能遇到的其他方法的問題?或者你可以添加一個解釋的參考?我不明白你寫了什麼。 – Subway

+0

謝謝! +1進行闡述。我仍然有一個問題:據我所知,你的觀點是編譯代碼,並保存編譯不必要的代碼。 鑑於我的代碼編譯,有沒有實際的麻煩(如意外行爲),我可能遇到在運行時使用第一種方法? – Subway

+0

@Subway否我認爲編譯器將boost :: is_fundamental :: value視爲一個常量,並將刪除未使用的代碼,因此不存在運行時開銷並且沒有UB。該方法是完全編譯它。 const值成員用於std :: enable_if(作爲整數模板參數),當然也用於演示(如打印值)。我認爲,對於其他任何目的,您都應該通過功能重載進行巡視。 –