在一些性病模板功能的描述我看到的东西,如:如何检查模板的参数类型是否为整数?
如果模板参数是整体式的,行为是如此这般。
否则,就是这样和那样的。
我该怎么做类似的测试?也许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