C++模板限制

And*_*rew 9 c++ templates

我想知道有没有办法对模板类设置限制?
指定模板中替换的每个类型必须具有特定的祖先(实现一些接口).

template < class B > //and every B must be a child of abstract C
class A {
public:
    B * obj;
    int f() {
        return B::x + this->obj->f();
    }
};
Run Code Online (Sandbox Code Playgroud)

喜欢=> in haskell

func :: (Ord a, Show b) => a -> b -> c
Run Code Online (Sandbox Code Playgroud)

Jam*_*kin 6

未来的C++版本将使用概念本身支持这种概念(它没有进入C++ 11).

解决问题的一种方法是在虚拟模板参数上使用特化:

class C {};
template <class B, class dummy=void>
class A;

template <class B>
class A<B, typename enable_if<is_base_and_derived<C, B> >::type>
{
    // class definition here
};

struct D : C {};

A<D> d;     // fine
A<int> n;   // compile error - undefined class A<B>
Run Code Online (Sandbox Code Playgroud)

我已经把单机的定义enable_ifis_base_and_derived 这里.


SLa*_*aks 2

您可以使用BOOST_STATIC_ASSERT或类似的库来断言对模板参数的限制。

例如:

#include <limits>
#include <boost/static_assert.hpp>

template <class UnsignedInt>
class myclass
{
private:
   BOOST_STATIC_ASSERT((std::numeric_limits<UnsignedInt>::digits >= 16)
                        && std::numeric_limits<UnsignedInt>::is_specialized
                        && std::numeric_limits<UnsignedInt>::is_integer
                        && !std::numeric_limits<UnsignedInt>::is_signed);
public:
   /* details here */
};
Run Code Online (Sandbox Code Playgroud)

编辑:对于你的例子,你可以写

template < class B >
class A {
    BOOST_STATIC_ASSERT(boost::is_base_of<C, B>);

public:
    B * obj;
    int f() {
        return B::x + this->obj->f();
    }
};
Run Code Online (Sandbox Code Playgroud)