免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3073 | 回复: 14
打印 上一主题 下一主题

没见过的东东,大家帮忙看看 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-02-29 11:05 |只看该作者 |倒序浏览
  1.     template <typename T>
  2.     bool is_class(int T::*) {
  3.         return true;
  4.     }
复制代码
这里面的int T::* 是啥玩意啊……

论坛徽章:
0
2 [报告]
发表于 2012-02-29 11:15 |只看该作者
成员指针

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
3 [报告]
发表于 2012-02-29 11:15 |只看该作者
  1. template <typename T>
  2. bool is_class(int T::*) {
  3.     return true;
  4. }

  5. struct foo
  6. {
  7.         int a;
  8. };

  9. int main()
  10. {
  11.         is_class( &foo::a );
  12. }
复制代码

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
4 [报告]
发表于 2012-02-29 11:17 |只看该作者

论坛徽章:
0
5 [报告]
发表于 2012-02-29 14:26 |只看该作者
本帖最后由 liwangli1983 于 2012-02-29 14:31 编辑

啊……原来是这个,怪不得看着有些眼熟但又完全想不起来了……当初看c++ primer的时候这块没怎么仔细看,事后也没再用到过……看了3楼的例子明白过来了。谢谢楼上2位解答

论坛徽章:
0
6 [报告]
发表于 2012-02-29 14:28 |只看该作者
bruceteen 发表于 2012-02-29 11:17
http://www.haogongju.net/art/799552


嗯,我看的就是这个。不过说来,虽然成员指针明白过来了,但那个Test里面并没有int型的成员,也能匹配成功???而且0算什么,null指针?

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
7 [报告]
发表于 2012-02-29 15:26 |只看该作者
但那个Test里面并没有int型的成员
------ 不需要“成员”,因为 int T::* 只是一个类型
C++规定 0可以隐式转化为任意指针类型

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
8 [报告]
发表于 2012-02-29 16:18 |只看该作者
回复 6# liwangli1983

不需要T有int成员……
只要T是class/struct/union, 就可以有 X T::*(成员数据指针类型) 和 成员函数指针类型(orz,我已经忘记这货怎么写了……)
只是如果T没有int成员就无法指向……

  1. #include <time.h>

  2. template<int> struct error_message;

  3. template<typename T>
  4. char is_class(T /*1*/ T::*);

  5. template<typename T>
  6. long is_class(...);

  7. error_message<sizeof(is_class<tm>(0))> tm_;
  8. error_message<sizeof(is_class<double>(0))> double_;
复制代码
1. 被指向的类型其实是什么都无所谓……
一般用int,因为写起来短……
这里用的 T T::*,其实根本不可能存在一个类型T,它有一个类型为T的成员…… 这只是为了极端演示这里其实什么类型都无所谓……  T T::* 是否合法我也不知道……
保险还是用int T::*

2. 返回类型,我选char与long只是因为"char","long"长度相同…… 于是两个is_class就对得齐……
至于应该选什么类型,后面再说……

3. is_class<tm>(0), 因为tm是struct/class/union,所以有int tm::*类型(同上,我不知道tm tm::*是否合法……)。
那就够了,0可以转换成这个类型(一个成员指针)的空值,返回char的is_class比返回long的更匹配,于是sizeof返回sizeof(char)。

4. is_class<double>(0),int不是struct/class/union,所以不存在double int::*类型。
但is_class(int T::*) —— 或者上面的例子is_class(T T::*) —— 失败了也没关系…… 只要能找到一个成功的就行……
long is_class(...) 就是为了产生一个总是成功的东西…… 于是sizeof 返回sizeof(long)。

编译上面的代码,看编译错误就知道了。。。



回到2,返回类型……  标准只保证sizeof(char)<=sizeof(long), 存在相等的情况……

于是,最通常的做法是让一个返回U,让另一个返回一个结构体,结构体包含U的数组,维度>=2。 于是两者大小肯定不相同了……
通常,U=char, 维度=2, 而且也不会直接返回U, 而是再搞一个结构体…… 于是就产生了:

  1. struct yes { char a; }; // 或者 char a[1];
  2. struct no { char a[2]; };

  3. template<typename T>
  4. yes is_class(int T::*);
  5. template<typename T>
  6. no is_class(...);

  7. #define IS_CLASS(T) ( sizeof(yes)==sizeof(is_class<T>(0)) )
复制代码
呃,我自己不太喜欢定义那两个类型……  对不齐是一个原因……(强迫症……)  示例代码短,多写两行就多了一倍代码……
于是可以利用一些预定义的, 比如pair<int,int> 肯定比int大, tm也是……
但这样又需要包含utility或者time.h

于是…… 终极做法…… 返回U的数组的引用……  char最方便,因为sizeof(char)==1,可以少写一次sizeof……

  1. template<int> struct error_message;

  2. template<typename T>
  3. char (&is_class(int T::*))[1];

  4. template<typename T>
  5. char (&is_class(...))[2];

  6. #define IS_CLASS(T) ( 1==sizeof(is_class<T>(0)) )

  7. error_message<IS_CLASS(tm)> tm_;
  8. error_message<IS_CLASS(double)> double_;
复制代码
而且yes/no只能返回两种值, 直接返回引用可以支持多种值……

论坛徽章:
0
9 [报告]
发表于 2012-03-01 09:54 |只看该作者
原来是这样,怪不得那些示例都要写成char和char[2]之类的……谢谢楼上各位了!

不过说来返回数组引用,不用typedef,看着还真有点让人眼晕

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
10 [报告]
发表于 2012-03-01 12:37 |只看该作者
回复 9# liwangli1983

用typedef的话,还是 struct no { char a[2]; }; 比较好……
typedef char (&no)[2]; 同样会被打……
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP