2013-11-28 35 views
1

我收到以下錯誤,當試圖將一個派生類的boost::shared_ptr轉換成父類的boost::shared_ptr的:說明的boost :: sp_convertible

1>c:\program files\boost\boost_1_52_0\boost\smart_ptr\detail\sp_convertible.hpp(48) : error C2594: 'argument' : ambiguous conversions from 'Title_Id_Record *' to 'Component::Interface *' 
1>  c:\program files\boost\boost_1_52_0\boost\smart_ptr\detail\sp_convertible.hpp(66) : see reference to class template instantiation 'boost::detail::sp_convertible<Y,T>' being compiled 
1>  with 
1>  [ 
1>   Y=Title_Id_Record, 
1>   T=Component::Interface 
1>  ] 

這裏是繼承圖,根據Doxygen的,對於Title_Id_Record: (所有繼承是公共的。) enter image description here

這裏是​​結構的文本:

template< class Y, class T > struct sp_convertible 
{ 
    typedef char (&yes) [1]; 
    typedef char (&no) [2]; 

    static yes f(T*); 
    static no f(...); 

    enum _vt { value = sizeof((f)(static_cast<Y*>(0))) == sizeof(yes) }; 
}; 

我的問題:

  1. 如何檢測 兼容性boost::sp_convertible結構工作?
  2. 爲什麼升壓共享指針Title_Id_Record不可轉換 到共享指針Component::Interface

謝謝。

僅供參考,我在使用Boost 1.52.0的Windows Vista上使用Visual Studio 2008。

編輯1:SCCE

namespace Component 
{ 
    class Interface {}; 
} 

namespace Record 
{ 
    class Interface 
     : public ::Component::Interface 
    {}; 
    class Table_Association 
     : public Record::Interface 
    {}; 
    class With_Id 
     : public Record::Table_Association 
    {}; 
    class Of_Shared_Pointers 
     : public Record::Table_Association 
    {}; 
    class Shared_Ptr_With_Id 
     : public Record::With_Id, 
      public Record::Of_Shared_Pointers 
    {}; 
    class Shared_Ptr_Id_String 
     : public Record::Shared_Ptr_With_Id 
    {}; 
    class Title_Id_Record 
     : public Record::Shared_Ptr_Id_String 
    {}; 

} 
+0

此圖上雙箭頭的含義是什麼? –

回答

3

我打賭的Record::Table_Association繼承是非virtual:在這種情況下,你在你的繼承子對象的兩個層次和編譯器不知道哪些一個可供選擇。這裏是一個例子:

// #define USE_VIRTUAL 
struct CInterface {}; 
struct RInterface: CInterface {}; 
struct RTableAssociation: RInterface {}; 
struct RWithId: USE_VIRTUAL RTableAssociation {}; 
struct ROfSharedPointers: USE_VIRTUAL RTableAssociation {}; 
struct RSharedPtrWithId: RWithId, ROfSharedPointers {}; 
struct TitleIdRecord: RSharedPtrWithId {}; 

int main() 
{ 
    TitleIdRecord r; 
    CInterface* c = &r; 
} 

(順便說一下,你也可以創建這個SSCCE)。要解決該問題,請取消註釋#define USE_VIRTUAL virtual一行。無論您是否使用boost::shared_ptr<T>這段代碼都無關緊要:類型特徵只是確定是否存在[非模糊]轉換。

+0

感謝您的良好檢查。但是boost :: sp_convertible如何工作? –

+0

@ThomasMatthews:它只是試圖用一個指向派生的,即Y *的指針來調用'f()'。如果被測試的類型'T'是一個基,'f(T *)'比'f(...)'更好匹配,結果的大小將是'yes'的大小,而不是'no'。也就是說,確實需要測試以確定測試的「值」是sizeof(f(static_cast (0)))== sizeof(yes)'。整潔的把戲。 –

+0

哦,我現在明白了,表達式f(..)實際上「調用」函數f(作爲constexpr),因此返回類型爲「f」的返回類型的實例。因此取其sizeof因此取得返回類型的大小。我被困惑的地方是在原文中他們使用括號,這使得它看起來像是在指向'f'。它不應該有一個可比較的尺寸。 –