2009-06-09 99 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