This is definitely a Visual C ++ compiler error. For some strange reason, the compiler cannot determine that Property<T>::IValue dereferenced from shared_ptr is a polymorphic base class and uses static type information to express typeid instead of typeid type information.
Minimum code to reproduce the error:
template <class T> struct Property { struct IValue { void f() {} virtual ~IValue() = 0 {} }; struct Value: IValue {}; Property(): m_pValue(new Value()) {
I played typeid with this sample a bit and found that typeid starts working as expected and displays the name of the runtime type if some function from a pointed object is called before typeid or if shared_ptr is replaced with unique_ptr . It's funny, but replacing shared_ptr<IValue> with IValue* still reproduces the error!
Actual conclusion:
Inside class: struct Property <int> :: Value
Outside class: struct Property <int> :: IValue
Expected (correct) conclusion:
Inside class: struct Property <int> :: Value
Outside class: struct Property <int> :: Value
From the assembler list, itβs clear that this is really a compiler problem:
typeid called from Property ctor generates an 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 , called externally, generates static information of type 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
Also note that the same error is present in VS2008, so this is an old time behavior.