我正在尝试实现is_base模板,我有“一点问题”。为什么这不起作用呢?
#include <iostream>
using std::cout;
class Car
{
};
class Fiesta : public Car
{
};
template<class Base, class Derived>
struct isBase
{
typedef char yes[2];
typedef char no[1];
template<class B, class D>
static yes& f(D* d, B* b = d);
template<class,class>
static no& f(...);
static bool type;
};
template<class Base, class Derived>
bool isBase<Base,Derived>::type = (sizeof(f<Base,Derived>(0,0)) == sizeof(yes));
int _tmain(int argc, _TCHAR* argv[])
{
cout << isBase<Fiesta,Car>::type;//It should say false here but says true
return 0;
}
答案 0 :(得分:2)
您明确地为指针提供了一个值:f<Base,Derived>(0, 0)
,此处不需要进行转换,尤其不是派生到基础的转换;此测试将始终通过,因为第一个测试始终是可调用的(任何指针都可以为null)。
你想要这样的东西:
template<class Base, class Derived>
struct isBase
{
typedef char yes[2];
typedef char no[1];
template <class B>
static yes& f(B*);
template <class>
static no& f(...);
// (1) make it const (as it should be) and just define it inline
// (2) it's not a type, it's a value; name appropriately
static const bool value = sizeof(f<Base>((Derived*)0)) == sizeof(yes);
};
// use a standard signature for main
int main() // if you don't need the arguments, don't list them
{
cout << isBase<Fiesta, Car>::value;
cout << isBase<Car, Fiesta>::value;
// return 0 is implicit for main, helpful for snippets
}
如果指针类型是或可以转换为Base*
,则将调用第一个重载。所以我们创建一个类型为Derived*
的指针,如果它实际上是一个派生类,那么转换将起作用,并调用第一个重载;否则,第二个。