2009-06-09 98 views
3

「無法轉換參數」我希望創建一個可以採取不同類型的存儲相同類型的對象的迭代器的功能:
第一個是包含shared_ptr<Foo>(的typedef - ED鏡頭作爲FooMap一個std::map ),另一個是std::list,其中還包含shared_ptr<Foo>FooList)。使用boost ::變種迭代

我真的很喜歡the solution MSalters suggested for a similar question並試圖實現boost::variant迭代器,該函數將作爲參數從第一個迭代到第二個。

我的功能看起來像這樣(簡化了不少):

set<Foo> CMyClass::GetUniqueFoos(FooIterator itBegin, FooIterator itEnd) 
{ 
    set<Foo> uniques; 
    for(/**/; 
     apply_visitor(do_compare(), itBegin, itEnd); // equals "itBegin != itEnd" 
     apply_visitor(do_increment(), itBegin))  // equals "++itBegin" 
    { 
     // Exact mechanism for determining if unique is omitted for clarity 
     uniques.insert(do_dereference< shared_ptr<Foo> >(), itBegin)); 
    } 

    return uniques; 
} 

的FooIterator和遊客,定義如下:

typedef 
    boost::variant< 
     FooMap::const_iterator, 
     FooList::const_iterator> 
    FooIterator; 

struct do_compare : boost::static_visitor<bool> 
{ 
    bool operator() (
     const FooMap::const_iterator & a, 
     const FooMap::const_iterator & b) const 
    { return a != b; } 

    bool operator() (
     const FooList::const_iterator & a, 
     const FooList::const_iterator & b) const 
    { return a != b; } 
}; 

struct do_increment: boost::static_visitor<void> 
{ 
    template<typename T> 
    void operator()(T& t) const 
    { ++t; } 
}; 

template< typename Reference > 
struct do_dereference: boost::static_visitor<Reference> 
{ 
    template<typename T> 
    Reference operator()(const T& t) const 
    { return *t; } 
}; 

我得到了最上面from the attachment of this mail的。根據MSalters的回答,該解決方案也使用適配器和策略,這似乎有點過分,所以我不想簡單地複製該代碼。特別是因爲我只理解它的一部分。

通過上面的代碼,我從VS2008中得到了以下編譯器錯誤(這只是總共160行的前幾行,我認爲這裏有點太多了,但是我很樂意將它們添加進去如果有人想看到這一切):

1>c:\boost\boost\variant\detail\apply_visitor_binary.hpp(63) : 
error C2664: 'bool CMyClass::do_compare::operator()(
const std::list<_Ty>::_Const_iterator<_Secure_validation> &, 
const std::list<_Ty>::_Const_iterator<_Secure_validation> &) const' : 
cannot convert parameter 1 from 'T0' to 
'const std::list<_Ty>::_Const_iterator<_Secure_validation> &' 
1>  with 
1>  [ 
1>   _Ty=shared_ptr<Foo>, 
1>   _Secure_validation=true 
1>  ] 
1>  Reason: cannot convert from 'T0' to 'const std::list<_Ty>::_Const_iterator<_Secure_validation>' 
1>  with 
1>  [ 
1>   _Ty=shared_ptr<Foo>, 
1>   _Secure_validation=true 
1>  ] 
1>  No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called 
1>  c:\boost\boost\variant\variant.hpp(806) : see reference to function template instantiation 'bool boost::detail::variant::apply_visitor_binary_invoke<Visitor,Value1>::operator()<T>(Value2 &)' being compiled 
1>  with 
1>  [ 
1>   Visitor=const CMyClass::do_compare, 
1>   Value1=T0, 
1>   T=T1, 
1>   Value2=T1 
1>  ] 
[...] 

我在做什麼錯?

回答

6

我懷疑你在do_compare static_visitor上丟失了案例。記住,變體可能有任何東西,所以你需要所有可能的組合,比如將FooList :: const_iterator與FooMap :: const_iterator進行比較。這是抱怨,因爲編譯器試圖爲這種情況找到一些匹配,並且不能將FooMap :: const_iterator轉換爲FooList :: const_iterator。

錘擊出來:

struct do_compare : boost::static_visitor<bool> 
{ 
    bool operator() (
     const FooMap::const_iterator & a, 
     const FooMap::const_iterator & b) const 
    { return a != b; } 

    bool operator() (
     const FooList::const_iterator & a, 
     const FooList::const_iterator & b) const 
    { return a != b; } 

    bool operator() (
     const FooMap::const_iterator & a, 
     const FooList::const_iterator & b) const 
    { return false; } 

    bool operator() (
     const FooList::const_iterator & a, 
     const FooMap::const_iterator & b) const 
    { return false; } 
}; 

下面是用模板的版本:

template <typename A, typename B> 
bool operator() (
    const A & a, 
    const B & b) const 
{ return false; } 

template <typename A> 
bool operator() (
    const A & a, 
    const A & b) const 
{ return a != b; } 

它編譯於科莫,但我不是100%它會工作,所以需要進行一些測試。除了更清潔,更通用的代碼之外,只要它能正常工作,它應該沒有任何影響。

+0

太棒了,那有效!謝謝! 我不知道你爲什麼刪除評論與模板雖然。使用它們有沒有副作用? – foraidt 2009-06-09 15:31:51