如何为模板函数指定可能的数据类型

时间:2011-06-17 21:45:23

标签: c++ templates

我正在尝试创建一个带有两种数据类型的函数,我知道它们都是drawable类的后代,这意味着我的函数依赖于drawable函数的某些函数。但是因为它是模板功能,所以我不能这样做。

我怎样才能使用这些后代类函数?或者只允许drawable的后代被接受?

这是我的功能的开始。 GetPositionY是drawable的函数。

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2){
    obj1->GetPositionY;

4 个答案:

答案 0 :(得分:3)

CheckCollision()函数应要求客户端传递提供GetPosition()方法的对象。这就是你在模板中调用obj1->GetPositionX()时所做的事情。没有理由强迫它传递drawable对象。

答案 1 :(得分:2)

使用以下组合:

来自Boost.TypeTraits的

boost :: is_base_of http://www.boost.org/doc/libs/1_46_1/libs/type_traits/doc/html/boost_typetraits/reference/is_base_of.html

和boost :: enable_if

http://www.boost.org/doc/libs/1_46_1/libs/utility/enable_if.html

template<typename T, typename T2>
typename boost::enable_if< boost::is_base_of< Drawable, T1>, bool>::type 
CheckCollision(T* obj1, T2* obj2)
{
  obj1->GetPositionY(); // ... whatever
}

答案 2 :(得分:2)

与C#不同,C#假定最低公分母并且需要使用“where”子句来解决这个问题,C ++采用的方法是不检查模板类型的用法,直到用特定类型实际调用该方法。因此,只有提供所需方法的类型才会编译。 e.g。

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2) {
        obj1->GetPositionY;
}

class A
{
        public:
                int GetPositionY;
                A() { };
};

class B
{
        public:
                B() { };
};

int main(int argc, char* argv[])
{
        A a;
        B b;

        // this compiles just fine
        CheckCollision(&a, &a);
        // this line will not compile, "error: 'class B' has no member named 'GetPositionY'"
        // CheckCollision(&b, &b);

        return 0;
}

对C#和C ++泛型here.

的这种差异进行了讨论

答案 3 :(得分:0)

drawable类添加一个特征结构,您可以使用它来测试模板中实例化的类型是否是正确的类型。这看起来像

//default for any data-type
template<typename T>
struct drawable_type
{
    enum { drawable = 0 };
};

//specialization for a drawable class
template<>
struct drawable_type<drawable>
{
    enum { drawable = 1 };
};

template<typename T, typename T2>
bool CheckCollision(T* obj1, T2* obj2) 
{ 
    if (drawable_type<T>::drawable && drawable_type<T2>::drawable)
    {
        //do something
    }
    else
        return false; 
}

现在,如果过去的类型不是可绘制的,那么你的函数将只返回false,否则你可以继续测试并查看是否发生了碰撞。