现在我们知道Concepts不是C ++ 0x的一部分,我正在寻找对模板函数中的类型施加限制的方法。
以下是两个例子:
如果我们想确保给定类型是整数,我们可以使用:
template <class N> inline int f(const N n)
{
if ((N)0.1 != 0) // if type of N is floating-point
err()
....
}
如果我们想确保给定类型是无符号整数,我们可以使用:
template <class N> inline int f(const N n)
{
if ((N)-1 < (N)1) // if type of N is floating-point / signed-integer
err()
....
}
我正在寻找创造性的方法来检查其他限制,这些限制会导致运行时失败,或者更好,在编译时(没有概念和没有RTTI)。
有什么建议吗?
答案 0 :(得分:12)
通过使用type-traits,可以在编译时更好地处理您的检查。
第一个:
STATIC_ASSERT(std::numeric_limits<N>::is_integer)
第二个:
STATIC_ASSERT(not std::numeric_limits<M>::is_signed)
答案 1 :(得分:2)
您可以通过扩展SFINAE近似限制功能模板。这是一个在C ++ 0x模式下实际编译GCC 4.4.1的例子:
#include <iostream>
#include <type_traits>
#define REQUIRES(...) ,class=typename std::enable_if<(__VA_ARGS__)>::type
template <typename IntType
REQUIRES( std::is_integral<IntType>::value )
>
inline IntType f(IntType n) {
return n;
}
int main() {
std::cout << f( 2) << '\n';
// std::cout << f(3.1415) << '\n'; // won't work
}
关于SFINAE的好处是,当模板参数推断失败时,函数模板将被忽略,并且不会成为重载集的一部分。上面的示例利用了C ++ 0x将支持函数模板的默认模板参数的事实。在旧的C ++ 98中,它看起来像这样:
template <typename IntType>
inline
typename boost::enable_if_c<(
std::numeric_limits<IntType>::is_integer
),IntType>::type f(IntType n) {
return n;
}
干杯, 小号
答案 2 :(得分:0)
要轻松检查继承,您也可以
template <typename T>
class MyClass
{
private:
static ClassA *checkIfTIsA() { return (T *)NULL; }
};