阅读C++ Templates一书中的问题
中文版259页中
我想问的是,下面的
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
是一个什么意思?是一个什么语法?
IsClassT<T>::test<T>(0)
这里的这个 0 是什么意思??????
// traits/isclasst.hpp
template<typename T>
class IsClassT {
private:
typedef char One;
typedef struct { char a[2]; } Two;
template<typename C> static One test(int C::*);
template<typename C> static Two test(…);
public:
enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
enum { No = !Yes };
};
// traits/isclasst.cpp
#include <iostream>
#include "isclasst.hpp"
class MyClass {
};
struct MyStruct {
};
union MyUnion {
};
void myfunc()
{
}
enumE{e1}e;
// check by passing type as template argument
template <typename T>
void check()
{
if (IsClassT<T>::Yes) {
std::cout << " IsClassT " << std::endl;
}
else {
std::cout << " !IsClassT " << std::endl;
}
}
// check by passing type as function call argument
template <typename T>
void checkT (T)
{
check<T>();
}
int main()
{
std::cout << "int: ";
check<int>();
std::cout << "MyClass: ";
check<MyClass>();
std::cout << "MyStruct:";
MyStruct s;
checkT(s);
std::cout << "MyUnion: ";
check<MyUnion>();
std::cout << "enum: ";
checkT(e);
std::cout << "myfunc():";
checkT(myfunc);
}
[解决办法]
0 is a smart argument. There are 2 test functions. During overloading deducation, it is more prior that converting 0 to pointer to class member than matching 0 with various parameter. So if T is class type, static One test(int C::*) will be instantiated, otherwise static Two test(…) will be instantiated. BTW: you must be noticed that Substitution Failure Is Not An Error (SFINAE)