ok!主题是:检查型别A与B是不是有继承关系,在本书的P38,下面直接上代码。
#pragma once
template<class T, class U>
class Conversion
{
typedef char Small;
class Big{ char dummy[2]; };
static Small Test(U);
static Big Test(...);
static T MakeT();
public:
enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
enum { exists2Ways = exists && Conversion<U, T>::exists };
enum { sameType = false };
};
template<class T>
class Conversion < T, T >
{
public:
enum { sameType = true, exists = true, exists2Ways = true };
};
#define SUPERSUBCLASS(T, U) \
(Conversion<const T*, const U*>::exists && \
!Conversion<const T*, const void*>::sameType)
#define SUPERSUBCLASS_STRICT(T, U) \
(SUPERSUBCLASS(T, U) && \
!Conversion<const T, const U>::sameType)
void chapter2_CI_CI()
{
cout << "<int->long>" << Conversion<int, long>::exists << "\n" << endl;
cout << "<char->char*>" << Conversion<char, char*>::exists << "\n" << endl;
cout << "<std::size_t->vector<int>>"
<< Conversion<std::size_t, std::vector<int>>::exists << "\n" << endl;
class A{};
class B : public A{};
cout << "SUPERSUBCLASS(A, B):" << SUPERSUBCLASS(A, B) << endl;
cout << "SUPERSUBCLASS(B, A):" << SUPERSUBCLASS(B, A) << endl;
cout << "SUPERSUBCLASS(int, long):" << SUPERSUBCLASS(int, long) << endl;
cout << "SUPERSUBCLASS(int, int):" << SUPERSUBCLASS(int, int) << endl;
cout << "SUPERSUBCLASS(char, char*):" << SUPERSUBCLASS(char, char*) << endl << endl;
cout << "SUPERSUBCLASS_STRICT(A, B):" << SUPERSUBCLASS_STRICT(A, B) << endl;
cout << "SUPERSUBCLASS_STRICT(B, A):" << SUPERSUBCLASS_STRICT(B, A) << endl;
cout << "SUPERSUBCLASS_STRICT(int, long):" << SUPERSUBCLASS_STRICT(int, long) << endl;
cout << "SUPERSUBCLASS_STRICT(int, int):" << SUPERSUBCLASS_STRICT(int, int) << endl;
cout << "SUPERSUBCLASS_STRICT(char, char*):" << SUPERSUBCLASS_STRICT(char, char*) << endl;
}
<int->long>1
<char->char*>0
<std::size_t->vector<int>>0
SUPERSUBCLASS(A, B):0
SUPERSUBCLASS(B, A):1
SUPERSUBCLASS(int, long):0
SUPERSUBCLASS(int, int):1
SUPERSUBCLASS(char, char*):0
SUPERSUBCLASS_STRICT(A, B):0
SUPERSUBCLASS_STRICT(B, A):1
SUPERSUBCLASS_STRICT(int, long):0
SUPERSUBCLASS_STRICT(int, int):0
SUPERSUBCLASS_STRICT(char, char*):0
请按任意键继续. . .
上面是代码和运行结果。使用win7+vs2013.
----------------------
我也是才学模板的,所以涉及不深,也说不上什么来。错误之处请指正。
他的转换是依赖函数的重载机制的。
像代码:enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };使用MakeT方法的返回值传给方法Test,而Test有2个版本,所以编译器择优选择,如果可以匹配到static Small Test(U),则可以转换,负责编译器只能选择static Big Test(...);,这时就表示不能转换,同时再依赖于sizeof的大小检测。这里应该都明白了, 但是看你会有一个问题,A不能转换为B,但是要是2个大小一样怎么办?请看: typedef char Small;class Big{ char dummy[2]; };
同时在检测类型一致时,使用了类模板偏特化的机制,函数是没有偏特化的。但是好像可以使用TYPE2TYPE来填坑。
类:
template<class T>
class Conversion < T, T >
这个类模板的声明呢,跟代码里其他一个模板类的声明不一样,一个是template<class T, class U>,一个就是template<class T>,但是这个类却使用了 class Conversion < T, T >,这个就是偏特化,如果你要定义一个类对象,如:Conversion (int ,int),那么编译器会选择模板参数只有一个的,如果你定义Conversion (int ,long),他会选择有两个模板参数的。模板偏特化还可以让你这么定义:
template<class T>
class Conversion < T, int >
这样不管T是什么,如果第二个参数是int,就会选择这个版本。
----------------------
不说了,免得误导人~~!