C++ 嵌套类上的RTTI,VS Bug?
以下代码输出:C++ 嵌套类上的RTTI,VS Bug?,c++,visual-studio-2010,C++,Visual Studio 2010,以下代码输出: struct属性::IValue 但我希望它能输出: struct属性::值 代码: struct IProperty { 虚拟~IProperty()=0; }; IProperty::~IProperty(){} 模板 结构属性:IProperty { 伊瓦鲁结构 { 虚拟~IValue()=0; }; 模板 结构值:IValue { Q事物; }; 属性():m_pValue(新值()){} std::共享值; }; 模板 属性::IValue::~IValue(){} i
struct属性::IValue
但我希望它能输出:
struct属性::值
代码:
struct IProperty
{
虚拟~IProperty()=0;
};
IProperty::~IProperty(){}
模板
结构属性:IProperty
{
伊瓦鲁结构
{
虚拟~IValue()=0;
};
模板
结构值:IValue
{
Q事物;
};
属性():m_pValue(新值()){}
std::共享值;
};
模板
属性::IValue::~IValue(){}
int main()
{
std::唯一的ptr p(新属性);
STD::CUT< P>这绝对是Visual C++编译器错误。由于一些奇怪的原因,编译器无法确定属性:IValue < /COD>从<代码> SyddYPPT/<代码>中被定义为多态基类,并使用“代码类型> Type ID < /C>表达式的静态类型信息代替运行时类型信息。
复制错误的最少代码:
template <class T> struct Property
{
struct IValue
{
void f() {}
virtual ~IValue() = 0 {}
};
struct Value: IValue {};
Property(): m_pValue(new Value())
{
// typeid inside class works as expected
std::cout << "Inside class: " << typeid(*m_pValue).name() << std::endl;
}
// If changed to unique_ptr typeid will work as expected
// But if changed to raw pointer the bug remains!
std::shared_ptr<IValue> m_pValue;
};
int main()
{
Property<int> p;
// If next line uncommented typeid will work as expected
//p.m_pValue->f();
std::cout << "Outside class: " << typeid(*p.m_pValue).name() << std::endl;
}
预期(正确)输出:
Inside class: struct Property<int>::Value
Outside class: struct Property<int>::IValue
Inside class: struct Property<int>::Value
Outside class: struct Property<int>::Value
外部调用的typeid
生成静态IValue
类型信息:
; 237 : std::cout << typeid(*p.m_pValue).name() << std::endl;
... irrelevant code skipped ...
; __type_info_root_node
push OFFSET ?__type_info_root_node@@3U__type_info_node@@A
mov ecx, OFFSET ??_R0?AUIValue@?$Property@H@@@8
;237:std::cout FWIW linux上的g++4.6.3和clang++3.2都给出了属性::值
(通过c++filt-t管道输出后)在我看来,这是一个bug,它返回的是静态类型而不是动态类型,并且静态类型是一个抽象基类。不过,我有几个问题:我认为嵌套结构值需要定义一个析构函数,因为它在基类中是纯虚的,尽管我必须查找它。如果您将dtor设为非纯虚的呢同样的情况也适用于struct属性。此外,如果将typeid()
拆分为多个表达式,会发生什么情况?
; 225 : std::cout << typeid(*m_pValue).name() << std::endl;
... irrelevant code skipped ...
; __type_info_root_node
push OFFSET ?__type_info_root_node@@3U__type_info_node@@A
mov ecx, DWORD PTR _this$[ebp]
; std::tr1::shared_ptr<Property<int>::IValue>::operator*
call ??D?$shared_ptr@UIValue@?...<skipped>
push eax
call ___RTtypeid
; 237 : std::cout << typeid(*p.m_pValue).name() << std::endl;
... irrelevant code skipped ...
; __type_info_root_node
push OFFSET ?__type_info_root_node@@3U__type_info_node@@A
mov ecx, OFFSET ??_R0?AUIValue@?$Property@H@@@8