关于模板的问题(关于loki)

hityct1 2008-01-04 09:26:22
#include "stdafx.h"

//判断型别T是否为Array
template<typename T>
class IsArray
{
template <typename> struct Type2Type2 {};

typedef char (&yes)[1];
typedef char (&no) [2];

template<typename U, size_t N>
static void vc7_need_this_for_is_array(Type2Type2<U(*)[N]>);

template<typename U, size_t N>
static yes is_array1(Type2Type2<U[N]>*);
static no is_array1(...);

template<typename U>
static yes is_array2(Type2Type2<U[]>*);
static no is_array2(...);


public:
enum { //是Array则value为1
value =
sizeof(is_array1((Type2Type2<T>*)0)) == sizeof(yes) ||
sizeof(is_array2((Type2Type2<T>*)0)) == sizeof(yes)
};

};

int _tmain(int argc, _TCHAR* argv[])

{
IsArray<double[]> da;
printf("%d\n",da.value);
printf("%d\n",IsArray<double[]>::value);


IsArray<double[5]> da2;
printf("%d\n",da2.value);
printf("%d\n",IsArray<double[5]>::value);

IsArray<double> d;
printf("%d\n",d.value);
printf("%d\n",IsArray<double>::value);

IsArray< std::vector<int> > v;
printf("%d\n",v.value);
printf("%d\n",IsArray< std::vector<int> >::value);

return 0;
}

谁能解释一下
enum { //是Array则value为1
value =
sizeof(is_array1((Type2Type2<T>*)0)) == sizeof(yes) ||
sizeof(is_array2((Type2Type2<T>*)0)) == sizeof(yes)
};
这一句?
...全文
178 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
fish6344 2008-01-04
  • 打赏
  • 举报
回复
这是利用enum和sizeof运算子以及模板的静态特性,在编译期实现类型识别的一种典型范例:

enum
{ //是Array则value为1
value = sizeof(is_array1((Type2Type2 <T> *)0)) == sizeof(yes)
|| sizeof(is_array2((Type2Type2 <T> *)0)) == sizeof(yes)
};

其中的is_array1及is_array2两个模板函数都不会被实际调用,因为sizeof只关心它们的返回类型,并于编译期得出计算结果。

如果T是数组,则:

sizeof(is_array1((Type2Type2 <T> *)0)) == sizeof(yex);//本表达式计算结果为true;

进而:

sizeof(is_array1((Type2Type2 <T> *)0)) == sizeof(yes)
|| sizeof(is_array2((Type2Type2 <T> *)0)) == sizeof(yes)

表达式计算结果为true;

相应的:

value = 1;//(true)!

否则,

#1. sizeof(is_array1((Type2Type2 <T> *)0)) == sizeof(yes););//本表达式计算结果为false;

#2. sizeof(is_array2((Type2Type2 <T> *)0)) == sizeof(yes) ;

其中#2行中左端计算结果为no(2个char),所以,#2表达式的总逻辑值是false。

因此同理:vulue = 0;//(false)!

由于上述is_array1及is_array2的函数参数仅供模板参数类型推导,没有实际使用,故设计者在两个函数中均以值为0的指针(Type2Type2 <T> *)作为参数以供编译时进行模板参数类型推导,进而推出T是何物,以决议出is_array1和is_array2相应的版本,进而得出相应的返回值类型以供sizeof运算!



  • 打赏
  • 举报
回复
(Type2Type2 <T> *)0
就跟
(int*)0类似
强制转换0为某种类型的指针.
hityct1 2008-01-04
  • 打赏
  • 举报
回复
我主要不明白(Type2Type2 <T> *)0 是什么意思。好像没人解释。。。
《Modern C++ Design》看了,没找到。
hastings 2008-01-04
  • 打赏
  • 举报
回复
这个不错。
这应该是那个叫做"不能匹配并非错误"的原则。
这种通常都有一个参数为...的一个函数,来匹配不能匹配的参数类型。
我把你里面的东西弄出来,就会有如下的程序:
template<typename>
struct A{};
template<typename T,size_t N>
void foo(A<T[N]>*)
{
cout<<"["<<N<<"]\n";
}
template<typename T>
void foo(A<T[]>*)
{
cout<<"[ ]\n";
}
void foo(...)
{
cout<<"非数组\n";
}
int main()
{
A<int[10]> a;
A<int[]> b;
A<int*> c;
A<int> d;
A<vector<int> > e;
foo(&a);
foo(&b);
foo(&c);
foo(&d);
foo(&e);
////////////////////////////////////////////////////////
system("PAUSE");
return 0;
}
  • 打赏
  • 举报
回复
通过判断,是否 有数组指针类型
taodm 2008-01-04
  • 打赏
  • 举报
回复
《Modern C++ Design》上有讲的,先去看书,不要急着看loki源码。
ttzzgg_80713 2008-01-04
  • 打赏
  • 举报
回复
没细看。ms是比较数组大小的
hityct1 2008-01-04
  • 打赏
  • 举报
回复
不行,难道要一天后才能加分?
taodm 2008-01-04
  • 打赏
  • 举报
回复
点“管理”
hityct1 2008-01-04
  • 打赏
  • 举报
回复
怎么加分?没搞明白。
hityct1 2008-01-04
  • 打赏
  • 举报
回复
我脑袋转过弯了。is_array1和is_array2要求传入的是变量,而不是型别。
作了如下改动,也是可以的:

static Type2Type2<T> parm;

enum { //是Array则value为1
value =
sizeof( is_array1(&parm) ) == sizeof(yes) ||
sizeof( is_array2(&parm) ) == sizeof(yes)
};

表达麻烦了些,但易于理解。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧