gpt4 book ai didi

c++ - 嵌套类上的 RTTI,VS Bug?

转载 作者:可可西里 更新时间:2023-11-01 17:57:01 24 4
gpt4 key购买 nike

以下代码输出:

struct Property<int>::IValue

但我希望它输出:

struct Property<int>::Value<int>

代码:

struct IProperty
{
virtual ~IProperty() = 0;
};

IProperty::~IProperty(){}

template<typename T>
struct Property : IProperty
{
struct IValue
{
virtual ~IValue() = 0;
};

template<typename Q>
struct Value : IValue
{
Q thing;
};

Property() : m_pValue(new Value<T>()){}
std::shared_ptr<IValue> m_pValue;
};

template<typename T>
Property<T>::IValue::~IValue(){}

int main()
{
std::unique_ptr<IProperty> p(new Property<int>);

std::cout << typeid(*static_cast<Property<int>&>(*p).m_pValue).name() << '\n';
}

如果IValueValue被移出Property这样它们就不再是嵌套类了,我得到了我期望的结果。这是 VS 错误还是预期行为?

最佳答案

这绝对是 Visual C++ 编译器错误。由于某些奇怪的原因,编译器无法确定 Property<T>::IValueshared_ptr 取消引用是多态基类,并为 typeid 使用静态类型信息表达式而不是运行时类型信息。

重现错误的最少代码:

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;
}

我试了一下这个样本,发现 typeid如果在 typeid 之前调用了指向对象的某些函数,则开始按预期工作并显示运行时类型名称或者如果 shared_ptr替换为 unique_ptr .有趣,但要替换 shared_ptr<IValue>IValue*仍然重现错误!

实际输出:

Inside class: struct Property<int>::ValueOutside class: struct Property<int>::IValue

Expected (correct) output:

Inside class: struct Property<int>::ValueOutside class: struct Property<int>::Value

From assembler listing it's clear that it's really compiler problem:

typeid called from Property ctor generates honest call to __RTtypeid:

; 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

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

另请注意,VS2008 中存在相同的错误,因此这是过去的行为。

关于c++ - 嵌套类上的 RTTI,VS Bug?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14566095/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com