typeof 运算符实现






3.84/5 (8投票s)
2004年8月7日
4分钟阅读

78707

359
Visual C++ 7.1 编译器的 typeof 运算符。
引言
C++ 标准中缺少的一个运算符是 typeof
运算符,它返回给定表达式的类型。它通常作为编译器扩展实现,但 Visual Studio 的 C++ 编译器 (7.1) 中仍然缺少它。
详细说明
然而,有一些 typeof
实现可以使用,它们可能都基于 Bill Gibbons 提出的一个非常简单但巧妙的想法 (http://www.accu-usa.org/2000-05-Main.html)。简而言之(如果这很难理解,可以跳过此段),要与 typeof
操作一起使用的每个类型都应单独注册,该注册会部分专门化(通过唯一索引)包含已注册类型的类。除此之外,还会引入一个新的函数重载,它将注册类型作为参数接收,并返回一个大小为先前类中使用的唯一索引的数组作为输出。
现在可以简单地实现 typeof
运算符:您需要一个表达式的类型;使用该表达式作为参数调用函数;计算 sizeof
返回值;将大小放入类模板参数中,并接收存储在那里的类型,该类型等于表达式类型!此外,所有这些都在编译时计算,因此,不需要实际的函数定义,这意味着不会引入额外的代码!这是一个绝妙的主意,后果很小(每个要使用的类型都应该注册,并且编译器速度会受到轻微影响)。
虽然没有文档记录(或者我没有在文档中找到),但似乎 Boost 的 MPL 包含一个 typeof 运算符实现,它适用于上述模式
BOOST_MPL_AUX_REGISTER_TYPE(123, abc);
abc aa1;
BOOST_MPL_AUX_TYPEOF(_, aa1) *aa2 = &aa1;
在我看来,Boost 解决方案的缺点是
- 它没有文档记录。
- 语法非常难看。
- 您必须手动为每个类型的注册过程提供唯一的索引。
- 您必须分别注册指针和常量类型。
- 如果您想注册模板实例,则必须使用 typedef,因为冒号不能放在 define 宏参数中。
- 错误消息不存在。
我已经尝试过,并希望成功地找到了所有列出问题的解决方法。
好了
- 你正在看它! :)
- 现在语法更清晰了! 类型注册是这样完成的
register_type hash_table<int, char *> for_typeof;
...而用法就像这样简单
hash_table<int, char *> var; typeof(&var) ptr = &var; for(typeof(var)::iterator it = var.begin(); it != var.end(); it++)
您可以看到代码变得更具可读性,您必须键入更少的内容,并且在类型(尤其是集合类)更改的情况下,您只需在一个地方进行修改。
请注意,如果您在注册过程中提供被指针、引用或
const
/volatile
修饰符污染的typedef
,它们将被删除。 此外,您可以随意在任何地方使用 typeof 运算符,用于局部变量、全局变量、类成员、基类等等。 - 如上所示,您只需要注册期间的类型! 唯一的索引由新 Visual Studio 中的
__COUNTER__
宏提供。 但是,不要认为这使得实现变得微不足道 - Boost 的预处理器库和模板专门化已被大量使用,因为每次使用__COUNTER__
宏都会给您不同的数字,而索引必须在注册过程中的许多地方使用! - 通过使用 Boost 的预处理器库(它同时非常强大但非常有限),该类型的指针会自动注册。 常量
TYPEOF_POINTER_LEVELS
(默认为 3)定义将注册多少个指针。 实际上,默认值就足够了。 较高的值(例如 50)会使编译器非常慢,而限制约为 80。 此外,最低级别的 const 修饰符也将被注册(其他组合的实现将非常复杂)。为了更清楚起见,注册后,使用默认的 pointer_levels 值,您将能够使用以下类型
hash_table<int, char *> hash_table<int, char *> * const hash_table<int, char *> * hash_table<int, char *> ** const hash_table<int, char *> ** hash_table<int, char *> *** const hash_table<int, char *> ***
- 已修复,没有其他评论。 :)
- 如果您尝试将 typeof 运算符应用于未注册的类型,则在第二个错误消息中,将提到 typeof_type_not_registered 类型,这应该更清楚地说明发生了什么。
我期待看到评论、改进、建议和更简单的解决方案!
要求
(未经先前版本测试)
-
Visual Studio 7.1
- Boost 1.31 (https://boost.ac.cn/)