2016-07-04 30 views
7

我試圖在一個嵌入式項目中使用shared_ptr,該嵌入式項目使用xc32 1.34(gcc 4.5.2的派生版)構建。該項目已通過-fno-rtti禁用RTTI。shared_ptr沒有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 

所以我想知道的是:這是一般不可能用shared_ptr沒有RTTI,還是我做錯了什麼?

+1

沒有RTTI的C++不再是C++。所有(我的意思是*全部*)投注都關閉。誰保證你可以在沒有RTTI的情況下使用''或''或''? –

+1

'shared_ptr'鍵入 - 擦除需要RTTI的刪除器。我認爲沒有辦法編寫自己的代碼或找到一個不這樣做的實現。不幸的是'boost :: shared_ptr'也支持刪除器,也許你可以找到一個沒有的版本。 – nwp

+3

@nwp類型擦除不需要RTTI。通常的模式是實現抽象類的模板包裝類。 – Quentin

回答

8

的問題是get_deleter免費功能:

template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept; 

返回:如果p擁有型CV -unqualified D的缺失者d,返回std:addressof(d);否則返回nullptr。只要存在一個擁有dshared_ptr實例,返回的指針就保持有效。

顯然,最直接的實現方式是將刪除器的typeid存儲在控制塊中。雖然還有其他可能的實現,但它們(a)會更復雜,(b)與啓用RTTI的代碼失去二進制兼容性,以及(c)違反-fno-rtti的「精神」。

另一個有問題的功能是dynamic_pointer_cast,它在存儲的指針上調用dynamic_cast

然而,shared_ptr的主要功能是可實現的,而無需使用RTTI功能,確實爲謝爾蓋Nikulov上面提到的shared_ptr附帶的gcc 4.8.5作品與-fno-rtti,隨着get_deleterdynamic_pointer_cast功能異常;只要你不使用這些設施,你就沒有理由不能使用shared_ptr。這可以與例如any,如果不使用typeid則無法實現。

供應商有責任提供一個標準庫,用於編譯器的所有配置,包括支持其使用的非標準庫。但是,如果您的供應商不合作,您仍然有幾個選擇:

  • 修補提供的標準庫以刪除損壞的get_deleter代碼;
  • 使用替代標準庫(例如更新的libstdC++或libC++);
  • 使用另一種智能指針功能(例如Boost)或自己寫一個智能指針功能。