在模板類中的函數中,我試圖區分基本類型和其他類型。C++:替代'std :: is_fundamental'?
在C++ 11,你可以這樣做:
if(std::is_fundamental<T>::value)
{
// Treat it as a primitive
}
else
{
//Treat it otherwise
}
請糾正我,如果我錯了,這是不是隻在C++ 11
是否有早期版本的C本的替代++ ?
在模板類中的函數中,我試圖區分基本類型和其他類型。C++:替代'std :: is_fundamental'?
在C++ 11,你可以這樣做:
if(std::is_fundamental<T>::value)
{
// Treat it as a primitive
}
else
{
//Treat it otherwise
}
請糾正我,如果我錯了,這是不是隻在C++ 11
是否有早期版本的C本的替代++ ?
你可以在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正常工作。
有了這段代碼,你會遇到麻煩。如果您需要區分不同的類型特徵,則必須在編譯時完成,而不是在運行時完成。根據您執行的操作,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_type
或false_type
。該結果用作選擇器,用於在編譯時選擇fun_impl
的正確過載,並且只對所選擇的過載進行實例化和編譯。
通常這種技術被用來在互聯網時間選擇一個最佳的實現,如果這些類型具有某些屬性,那麼這個實現可能只是可編譯的。
2日編輯:
當然這個變化的意願,如果static if
是語言的一部分。
可否請您詳細說明我可能遇到的其他方法的問題?或者你可以添加一個解釋的參考?我不明白你寫了什麼。 – Subway
謝謝! +1進行闡述。我仍然有一個問題:據我所知,你的觀點是編譯代碼,並保存編譯不必要的代碼。 鑑於我的代碼編譯,有沒有實際的麻煩(如意外行爲),我可能遇到在運行時使用第一種方法? – Subway
@Subway否我認爲編譯器將boost :: is_fundamental
謝謝。 「include」爲+1。 – Subway