在<現代C++設計>,它引入了一種方法來檢查是否通過引入所謂的類型列表來檢查類型的基本類型。但是如果我不想包含這麼多的loki代碼並且只想要一個簡單的函數來實現呢?什麼是最簡單的方法來做到這一點?有沒有簡單的方法來檢查基本類型
回答
你可以使用模板專門化來得到你想要的。
// General template
template<typename T>
struct IsFundamentalType { enum { result = false }; };
// Template specializations for each fundamental type
template<>
struct IsFundamentalType<char> { enum { result = true }; };
template<>
struct IsFundamentalType<int> { enum { result = true }; };
template<>
struct IsFundamentalType<short> { enum { result = true }; };
template<>
struct IsFundamentalType<float> { enum { result = true }; };
// And so on for other fundamental types ...
class NonFundamentalType
{
};
template<typename T>
void DoSomething(const T& var)
{
if(IsFundamentalType<T>::result)
{
printf("I'm fundamental type!\n");
}
else
{
printf("I'm not a fundamental type!\n");
}
}
int main()
{
int i = 42;
char c = 42;
short s = 42;
float f = 42.0f;
NonFundamentalType nft;
DoSomething(i);
DoSomething(c);
DoSomething(s);
DoSomething(f);
DoSomething(nft);
}
在此代碼,如果你在一個類型傳遞,例如int
或char
,編譯器將使用的IsFundamentalType
專業化(假設您已經定義了專業化的所有基本類型)。否則,編譯器將使用通用模板,因爲類是NonFundamentalType
類。重要的是,專用模塊的result
成員定義爲true
,而通用模板也有一個result
成員,定義爲false
。然後,您可以使用result
成員作爲if
語句。優化編譯器應該能夠忽略if
語句,看到表達式減少到一個常量的真/假值,所以做這樣的事情不應該強加運行時懲罰。
最簡單的方法是創建一個類型特徵對象。基本上,你創建一個對象(我們稱之爲is_fundamental <T>),該對象由類型參數化,並且默認從boost :: type_traits :: no_type繼承;那麼你在所有基本類型上專門化這個對象,使得這個專門化繼承自boost :: type_traits :: yes_type。那麼你可以使用is_fundamental <T> :: value作爲一個布爾值,它會告訴你T類型是否是基本類型。在大多數情況下,你確實不需要知道某個類型是否是基本類型,而當你這樣做時,它幾乎總是涉及到模板,不管怎樣,這樣做也可以。
我還應該指出,Boost已經定義了boost::type_traits::is_fundamental這是你想要的。你可以在is_fundamental.hpp中看到他們根據其他類型特徵對象來定義它;如果是內建的算術類型,或者類型是「無效」(也被認爲是基本的),則類型是基本的。試圖從升壓搞清楚這些事情可能是一種混亂,但簡化爲:
template<typename T, T VAL> struct constant_value
{
static const T value = VAL;
};
typedef constant_value<bool,true> yes_type;
typedef constant_value<bool,false> no_type;
template<typename T> struct is_fundamental : public no_type{};
// Create a macro for convenience
#define DECLARE_FUNDAMENTAL(X) \
template<> struct is_fundamental<X> : public yes_type{}
// Specialize for all fundamental types
DECLARE_FUNDAMENTAL(void);
DECLARE_FUNDAMENTAL(bool);
DECLARE_FUNDAMENTAL(signed char);
DECLARE_FUNDAMENTAL(unsigned char);
// ... lots more similar specializations ...
DECLARE_FUNDAMENTAL(wchar_t);
DECLARE_FUNDAMENTAL(float);
DECLARE_FUNDAMENTAL(double);
DECLARE_FUNDAMENTAL(long double);
// Prevent this macro from polluting everything else...
#undef DECLARE_FUNDAMENTAL
這實質上是如何才能創造這樣的類型traits對象。請注意,可以惡意地將類型特徵專門化爲非基本類型,儘管無論如何對於大多數情況都是如此。
然後,您可以使用上述來創建一個更具功能性的東西。例如,使用升壓:: type_traits :: is_fundamental類,你可以創建以下:
template<typename T>
bool isFundametal(const T&)
{
return boost::type_traits::is_fundamental<T>::value;
}
由於模板專業化可以從參數可以推斷,你可以調用這個函數isFundamental沒有明確指定類型。例如,如果您編寫isFundamental(5),它將隱式調用isFundamental <int>(5),它將返回true。但是請注意,如果您創建了這樣一個函數,它將不允許您測試void。你可以創建一個沒有參數的函數,但是這個類型不會被推導出來,所以它不會比簡單地使用boost :: type_traits :: is_fundamenta <T> :: value等更漂亮不妨在這種情況下使用它。
不重新發明輪子使用的boost :: type_traits
http://www.boost.org/doc/libs/1_42_0/libs/type_traits/doc/html/index.html
- 1. 有沒有簡單的方法來使用基類的變量?
- 2. 有沒有簡單的方法來檢查PowerShell腳本的向後兼容性?
- 3. 有沒有簡單的方法來檢查一個mp4文件是否有效?
- 4. 有沒有簡單的方法來加載listmodel中的泛型?
- 5. 有沒有簡單的方法來生成類似的顏色?
- 6. 有沒有簡單的方法來查找Facebook用戶的ID?
- 7. 有沒有簡單的方法來查看FormCollection的內容?
- 8. 有沒有一種簡單的方法來拼寫檢查與.NET中的TinyMCE
- 9. 有沒有簡單的方法來檢查/編輯存儲在nsIPrefBranch中的值?
- 10. 有沒有更簡單的方法來檢查Django模板中的M2M值?
- 11. 有沒有簡單的方法來檢查重複的快捷鍵?
- 12. 有沒有辦法來檢查方法返回的值的類型?
- 13. 有沒有簡單的方法來設置WPF StatusBar文本?
- 14. 有沒有簡單的方法來檢查系統上是否啓用了CredSSP?
- 15. 有沒有一種簡單的方法來檢查字段是否爲null?
- 16. 有沒有簡單的方法來處理基地13(或通用基地N)?
- 17. 有沒有簡單的方法來動畫ScrollableControl.ScrollControlIntoView方法?
- 18. 有沒有更好的方法來檢查數據通道中的類型?
- 19. 簡單的方法來檢查FormatString是否有效?
- 20. 簡單的方法來檢查在asp.mvc查看模型更改
- 21. 有沒有辦法逐行檢查簡單的Django查詢?
- 22. 有沒有簡單的方法來爲現有的類生成接口?
- 23. 有沒有簡單的方法來獲取基於給定路徑的folderID?
- 24. 有沒有更有效的方法來編寫這個簡單的SQL查詢?
- 25. 有沒有簡單的方法來查找框架的所有依賴關係?
- 26. 有沒有更簡單的方法來運行與JavaScript的SQLite?
- 27. 我是新來的d3,有沒有簡單的方法?
- 28. 有沒有簡單的JavaScript方法來操縱任意的URL?
- 29. 有沒有簡單的方法來寫在JavaScript中的Object.defineProperty
- 30. 有沒有更簡單的方法來解析Java中的Android?
但是,被這意味着引進Boost庫?或只有一個頭文件? – 2010-04-29 00:38:12
正確的方法是下載最新的boost,安裝它,編譯,然後在你的代碼中只包含需要的頭文件。你不應該將boost文件複製到你的項目中。 請注意,boost :: type_traits庫僅用於頭文件,您無需編譯即可使用它 – 2010-04-29 08:23:44