强加模板函数类型的约束,没有c ++ 0x概念

时间:2009-09-20 14:13:23

标签: c++

现在我们知道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)。

有什么建议吗?

3 个答案:

答案 0 :(得分:12)

通过使用type-traits,可以在编译时更好地处理您的检查。

第一个:

STATIC_ASSERT(std::numeric_limits<N>::is_integer)

第二个:

STATIC_ASSERT(not std::numeric_limits<M>::is_signed)

查看Boost Concept Check LibraryBoost.StaticAssert

答案 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; }
};