在一些性病模板功能的描述我看到的東西,如:如何檢查模板的參數類型是否爲整數?
如果模板參數是整體式的,行爲是如此這般。
否則,就是這樣和那樣的。
我該怎麼做類似的測試?也許dynamic_cast?
由於我寫的功能是供我個人使用的,我可以依靠自己提供唯一正確的參數,但爲什麼錯過了學習機會的機會呢? :)
在一些性病模板功能的描述我看到的東西,如:如何檢查模板的參數類型是否爲整數?
如果模板參數是整體式的,行爲是如此這般。
否則,就是這樣和那樣的。
我該怎麼做類似的測試?也許dynamic_cast?
由於我寫的功能是供我個人使用的,我可以依靠自己提供唯一正確的參數,但爲什麼錯過了學習機會的機會呢? :)
除了其他的答案,但應該注意的是,該測試可以在運行時也是在編譯時使用取決於選擇正確實施羯羊類型是整數或不:
運行版本:
// Include either <boost/type_traits/is_integral.hpp> (if using Boost)
// or <type_traits> (if using c++1x)
// In the following, is_integral shoudl be prefixed by either boost:: or std::
template <typename T>
void algorithm(const T & t)
{
// some code
if (is_integral<T>::value)
{
// operations to perform if T is an integral type
}
else
{
// operations to perform if T is not an integral type
}
// some other code
}
但是,這個解決方案可以改進時,當算法的執行很大程度上取決於測試。在這種情況下,我們將在該函數的頂部進行測試,然後是一個大塊then
塊和一個大塊else
塊。在這種情況下,常見的做法是重載函數並使編譯器使用SFINAE選擇正確的實現。一個簡單的方法來做到這一點是使用boost::enable_if
:
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/is_integral.hpp>
template <typename T>
typename boost::enable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for integral types
}
template <typename T>
typename boost::disable_if<boost::is_integral<T> >::type
algorithm(const T & t)
{
// implementation for non integral types
}
當調用algorithm
函數,編譯器將「選擇」視閹模板參數的正確實施是整體的或不是。
#include <type_traits>
#include <iostream>
struct trivial
{
int val;
};
int main()
{
std::cout << "is_integral<trivial> == " << std::boolalpha
<< std::is_integral<trivial>::value << std::endl;
std::cout << "is_integral<int> == " << std::boolalpha
<< std::is_integral<int>::value << std::endl;
std::cout << "is_integral<float> == " << std::boolalpha
<< std::is_integral<float>::value << std::endl;
return (0);
}
所以,你再使用std::is_integral<>
來確定動作。
Boost.TypeTraits提供了is_integral <>(),如另一個響應所述,如果您的編譯器還不支持下一個標準的C++特性。
可能不是,我剛剛檢查過我沒有type_traits包含文件。應該添加'linux'和'gcc'標籤... – davka 2010-08-11 13:43:58
@davka:這些標籤與boost無關。如果標題丟失,那麼您需要將正確的位置添加到標題的搜索路徑或安裝boost。 – 2010-10-23 10:36:44
如果您無法使用C++ 11功能,std::numeric_limits<T>::is_integer
將the same thing設置爲std::is_integral<T>::value
,並且可用於C++ 98。
請注意,98版本是inte ger,而不是intend gral。
非常有用,謝謝 – davka 2010-08-11 14:51:12
我會說每個值得它穀物的編譯器都會在你的第一個例子中消除死分支 - 它很簡單。 – 2010-08-11 15:18:27
@Georg Fritzsche:這是真的,這就是爲什麼我沒有提到潛在的性能增益。儘管如此,我認爲重載方法更清晰:兩種實現可以分開進化,並且我發現區分什麼是靜態(在編譯時已知/執行)和什麼是動態(在運行時已知/執行)之間更好。但是,那可能是因爲我花了太多時間在最後幾個月進行元編程! – 2010-08-11 15:38:48