注册 登录
编程论坛 C++教室

关于模板的疑惑

zhuxiaoneng 发布于 2013-04-16 16:25, 494 次点击
最近在看《C+++Templates》 这本书,关于下面的例子有些疑惑,请各位高手帮忙解答下,谢谢
程序代码:

#include <iostream>

using namespace std;

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 };
};

class MyClass
{

};
template <typename T>
void check()
{
        if (IsClassT<T>::Yes) {
                std::cout << " IsClassT " << std::endl;
        }
        else {
                std::cout << " !IsClassT " << std::endl;
        }
}

int main()
{
        std::cout << "int:  ";
        check<int>();

        std::cout << "MyClass: ";
        check<MyClass>();
}

这个是书上的源代码,但是在vs2008下编译不通过。


        enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };
        enum { No = !Yes };
改为:
        static bool isClass()
        {
                return sizeof(IsClassT<T>::test<T>(0)) == 1;
        }
可以顺利通过
1 请问这是为什么?

2 template<typename C> static One test(int C::*);   中参数的类型为
指向int  型的C 类的成员的指针
但是MyClass 中并没有int型的数据成员,为什么可以通过编译,并且顺利得到结果?

3 template<typename C> static One test(int C::*);  为什么需要写成模板函数?
   改写成:static One test(int T::*); 为什么不行??

谢谢大家帮忙解答下!
6 回复
#2
zhuxiaoneng2013-04-17 13:30
没人回答下么?
#3
peach54602013-04-17 14:46
感觉你模板完全不了解啊,不知道怎么跟你讲
这个东西你现在学为时尚早
#4
peach54602013-04-17 15:33
1,我不知道为什么枚举要转函数

2,计算机时几位的?int是几位的?

3,看概念去
#5
zhuxiaoneng2013-04-17 15:48
1  enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 };  这个不是枚举转函数啊, 先计算 sizeof(IsClassT<T>::test<T>(0)) == 1 这个会返回true或者false
   sizeof(IsClassT<T>::test<T>(0)) 这个通过返回值类型的大小,来判断实例化的是哪个函数
   template<typename C> static One test(int C::*)
   或者
   template<typename C> static Two test(...)

2  不知道你问的是什么意思, 我想问的是:
   
程序代码:
class MyClass
{
public:
    int _a;
    double _b;
};

void main()
{
    int MyClass::* p1 = &MyClass::_a;
    int MyClass::* p2 = &MyClass::_b;
    double MyClass::* p3 = &MyClass::_b;
}

    p2 是不可能通过编译的,说明int MyClass::*和double MyClass::*是不同的类型,那么为什么在MyClass中根本没有int型的数据成员时,
    模板IsClassT<MyClass>::test<MyClass>(0)推演时,还是可以匹配
     template<typename C> static One test(int C::*)
   
3  确实是看书不仔细,如果改写成static One test(int C::*) 整个就是个类模板,类模板不进行模板推导,所以也就不会应用SFINAE规则
#6
peach54602013-04-17 16:41
第二个我看错了,我以为你问的是另外一个问题
#7
zhuxiaoneng2013-04-17 17:16
想明白了,谢谢大家
1