我试图在嵌入式项目中使用shared_ptr
,该项目使用xc32 1.34(gcc 4.5.2的衍生版本)构建。该项目已禁用RTTI -fno-rtti
。
#include <memory>
只是包含标题会给我以下错误:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del<_Ty, _Dx>::_Get_deleter(const std::type_info&) const':
In file included from APP/MODULES/LIGHT_MANAGER/LightManager.cpp:13:0:
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1264:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In member function 'virtual void* std::tr1::_Ref_count_del_alloc<_Ty, _Dx, _Alloc>::_Get_deleter(const std::type_info&) const':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1299:39: error: cannot use typeid with -fno-rtti
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory: In function '_Dx* std::tr1::get_deleter(const std::tr1::shared_ptr<_Ty2>&)':
/Applications/microchip/xc32/v1.34/bin/bin/../../lib/gcc/pic32mx/4.5.2/../../../../pic32mx/include/Cpp/memory:1956:44: error: cannot use typeid with -fno-rtti
所以我想知道的是:没有RTTI通常不可能使用shared_ptr
,或者我做错了什么?
答案 0 :(得分:8)
问题是get_deleter
免费功能:
template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
返回:如果
p
拥有 cv -unqualifiedd
类型的删除者D
,则返回std:addressof(d)
;否则返回nullptr
。只要存在拥有shared_ptr
的{{1}}实例,返回的指针就会保持有效。
显然,最简单的实现方法是将删除器的d
存储在控制块中。虽然还有其他可能的实现,但它们会(a)更复杂,(b)失去与启用RTTI的代码的二进制兼容性,以及(c)违背&#34;精神&#34; typeid
。
另一个有问题的函数是-fno-rtti
,它在存储的指针上调用dynamic_pointer_cast
。
但是,dynamic_cast
的主要功能是在不使用RTTI功能的情况下实现的,事实上正如Sergei Nikulov上面提到的那样,gcc 4.8.5附带的shared_ptr
与shared_ptr
一起使用,-fno-rtti
和get_deleter
函数除外;只要您不使用这些设施,就没有理由不能使用dynamic_pointer_cast
。这可以与例如shared_ptr
,如果不使用any
,则无法实施。
供应商有责任提供适用于其编译器的所有配置的标准库,包括支持其使用的非标准库。但是,如果您的供应商不合作,您仍有一些选择:
typeid
代码;