| ||||
| 引用:
c++ 代码:
其中 c++ 代码:
|
| ||||
| 把话题岔得深一点, 首先,我前面回答里面有个错误,应该是std::typeid,而不是std::typeinfo 例如 代码:
代码:
其次说说类型系统,C++如此强的类型系统带来的优点多呢还是缺点多呢?如果C++中突然没有了类型,想想看,将是发生一些很有意思的事情。首先,模板突然没有用了,比如下面的函数模板: 代码:
代码:
代码:
如果变量x所属的类(注意,不是类型)没有定义func1,编译器就向x的父类找,找到了就调用,找不到就继续向上找,如果最终没有找到,就抛exception 这样的情形,其实并不新鲜,在许多脚本语言中,例如perl, python, ruby,以及smalltalk, LISP中这些都是司空见惯的。 但是C++采用了强类型,并且是静态强类型。结果是带领程序员们到了完全另一个世界。 |
| |||
| 我确实想得到int这个类型 我现在的实现是 用模板函数推导,函数参数增加一个哑元辅助 但是要用宏来辅助 template <typename _Ty> object_info make_object_info(const std: tring name , const _Ty * dummy = NULL );这个dummy是不会去用的,目的就是为了推导出_Ty 使用的时候 #define MEMBER_FIELD_BASE(MEMBER,NAME) \ { \ object_type * ot = NULL; \ desc.member_fields.push_back( make_object_info( NAME , &ot->##MEMBER ) ); \ } 其实也就是用一个哑元变量,来利用模板函数推导某个字段的类型 但是这样的代码很不通用,而且还是没有把类型取出来,只是用到了 局限性最大的就是他一定要用到代码实现,无法在只使用声明的阶段来确定,如果能做到只用声明,那就可以写出 TypeOf<X,X::a>::Result var; 这样的代码了 |
| ||||
| 引用:
c++ 代码:
gettype.cpp: In function `int main(int, char**)': gettype.cpp:55: error: expected `;' before '::' token 因为type_of()返回的是一个object,你无法对着Object使用::,来获取类模板内定义的Result,甚至更进一步,这个实现更直观,但是不能通过编译: 代码:
|
| ||||
| 另外给几个link 一个是gnu的增强RTTI实现,基本能够满足本问题的要求。下一代标准出来,估计就好了。 http://gcc.gnu.org/onlinedocs/gcc/Typeof.html 一个是目前boost::mpl给出的实现 http://www.codeproject.com/vcpp/stl/typeof.asp 最后一个是目前gnu的编译器的现状,typeof返回的是一个字符串。 http://www.mhatt.aps.anl.gov/dohn/so...ef/std-ts.html |
| ||||
| 这是个很老的问题了,问题的实质规约到底其实就是在现有的C++里面实现一个typeof设施来。好几年前一帮人在CSDN上就讨论过,印象中有ajoo,不过后来证明是不可行的,我当时也绞尽脑汁想了很久,意识到只有通过sizeof来对类型信息进行编码,然后再解码出来才是解决之道,但是就到这里,发现走不下去了,其实走得下去,只不过问题是没法实现一个完全通用的typeof来。比如吧: template<int N> struct size { char dummy_[N]; }; template<typename T> size<sizeof(T)> typeof_imp(T); template<> size<10> typeof_imp(int); template<int size_> struct type_of; template<> struct type_of<10> { typedef int type; }; #define TYPEOF( e) type_of<sizeof(typeof_imp( e))>::type 然后提供一个REGISTER宏,让用户来REGISTER自定义的类型,比如: #define REGISTER_TYPE(T) \ template<> \ size<GEN_UNIQUE_NUM(T)> typeof_imp(T); \ template<> struct type_of<GEN_UNIQUE_NUM(T)> \ { typedef T type; }; 这么一来,便实现了一个初级的”类型编码-还原“的框架。 REGISTER_TEMPLATE的实现大抵类似。 用的时候,只要先REGISTER你的自定义类型,如: struct MyC{}; REGISTER_TYPE(MyC) 然后后面就可以对任意的类型为MyC的表达式用: TYPE_OF( e) 了。 这个方案最大的缺点在于,它无法将一个复杂的类型分解为已知类型并各自推导,比如说,当它能够识别C和int的时候,无法让它能够自动识别出C<int>,你只能自行的再次REGISTER一下。这很不方便。因为类型的组合是无穷的。 于是卡在这里想不下去了 ![]() 直到发现BOOST_TYPEOF...茅塞顿开... |