代码之家  ›  专栏  ›  技术社区  ›  Lior Kogan

模板函数类型的约束,不含C++ 0x概念

c++
  •  3
  • Lior Kogan  · 技术社区  · 15 年前

    现在我们知道概念不是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 回复  |  直到 15 年前
        1
  •  12
  •   Konrad Rudolph    15 年前

    通过使用类型特征,可以在编译时更好地处理检查。

    第一:

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

    第二:

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

    看看 Boost Concept Check Library 及AT Boost.StaticAssert

        2
  •  2
  •   sellibitze    15 年前

    可以通过扩展sFANAE来近似受限的函数模板。下面是一个用GC4.4.1编译的C++ 0x模式的例子:

    #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;
    }
    

    干杯, S

        3
  •  0
  •   mmmmmmmm    15 年前

    为了方便地检查继承,您也可以这样做。

    template <typename T>
    class MyClass
    {
    private:
      static ClassA *checkIfTIsA() { return (T *)NULL; }
    };