编译器如何计算' typeid '操作符
How does compiler evaluate `typeid` operator?
这里是一些基于CRTP的模板代码,我用来尝试解决这个问题:要求覆盖的虚函数调用基实现。我会在这里发布代码,但是代码行很长,在codepad.org上更容易阅读(如果需要,我会在这里发布)。它很丑,而且有点做作,当然,尽管它确实有效。但我一开始没有意识到的是,虽然它在msvc++和GCC上都可以编译,但有些模板类型并没有真正定义。我质疑的部分是TBase::OnEvent
函数顶部的几个长内部if( typeid( Derived(N) ) != typeid( Derived(N-1))
(符号符号)。
你不能typdef
这些类型,这将是一个编译错误-没有足够的派生类的类型来定义这样长的...::TDerived::...
链,所以你会得到,正确的,编译错误TDerived is not defined in TBase
。然而,编译器通过typeid
吃掉了它们。当我检查调试器msvc++编译器输出(具有完整的符号信息)时,似乎所有那些长...::TDerived::...
都不应该真正导致任何类,在typeid
中由编译器解析为类链中的最后一个TDerived04
。RTTI是为类链中的最后一个类提取的,与我有多少个...::TDerived::...
无关。
考虑到msvc++和GCC都这样做(尽管我只能通过codepad.org访问GCC),我的问题是接下来:它是否以某种方式定义了typeid
的行为?那么为什么...::TDerived::...
中的typedef
不能解析为TDerived04
呢?
编辑:我的意思是,我很高兴typedef
不解决TDerived04
,这对任何使用typedef
的人来说都是灾难,但为什么typeid
和typedef
之间存在这种不一致?
TDerived04::TDerived04::TDerived04::TDerived04 lD4;
变量声明。最后的类型是简单的TDerived04
。是否有崩溃作用域解析的规则?显然,msvc++和GCC似乎在typeid
中做同样的事情,但是msvc++,不像GCC,不能处理其他场景-它给出编译错误,需要构造函数的参数。
我不会考虑使用typeid
作为除调试工具之外的任何东西。c++标准只保证它的存在,但并没有真正说明它应该做什么。这使得这个实用程序只不过是一种打印人类可读的类名的方法(如果您知道任何其他实际用途,请纠正我)。
我想说的是,typeid
有太多的"编译器定义"的行为,使得它对其他任何事情都有用。
方法也有一个巨大的缺点。除了丑陋和难以维护之外,基类还需要了解所有派生类。这是个很大的设计缺陷。
关于替代解决方案,可以在这里看到(代码也贴在原始问题中)。
至于TDerived04::TDerived04::TDerived04::TDerived04
是有效的,可以解释为在TDerived04类中,您可以使用其名称TDerived04来引用该类/命名空间。所以TDerived04::TDerived04就像从TDerived04指向类TDerived04(正如@MSalters所说的,它被称为"类名注入")。
问题大致是注入的类名和构造函数名之间存在歧义。在class X
的作用域中,X
可以命名类本身,但X::X
也可以引用构造函数,在有意义的地方。
- C++typeid模板值转换为联合不可接受的转换
- 使用typeid警告未使用的变量
- 如何在 lambda 中访问捕获的此指针的"typeid"?
- Visual Studio 2017 C++,不能使用 typeid() 获取信息对象,缺少指针?;
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- typeid 给出类型 m、j 和 Pj
- 在C++17中有typeid的反函数吗
- 为什么map有操作符[],set没有
- 如何实现构造函数,使其仅接受使用 typeid 的输入迭代器?
- typeid.name 返回派生类类型之前的数字
- 比较函数模板中的 VARTYPE 和 typeid().name / typename
- 返回别名标识符,而不是typeid(SOME_TYPE).name()中的类型
- typeid( " " ) != typeid(const char*)
- 将typeID转换为静态成员访问(C )的命名空间
- typeid 运算符忽略 cv 限定符背后的理由是什么?
- 为什么typeID().名称(),c 在输出中未显示const
- 当我将对象添加到向量时,为什么typeID名称会更改
- 汇编TypeID(OBJ)时会发生什么-C
- typeID检查有效后,使用reinterpret_cast
- 编译器如何计算' typeid '操作符