我想创建,可以采取不同类型的存储相同类型的对象的迭代器的功能:结果 第一个是包含std::map shared_ptr<Foo>(的typedef-ED作为FooMap),而另一个是一个std::list其中还包含shared_ptr<Foo>FooList)。

我很喜欢溶液MSalters建议一个类似的问题并试图执行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; }
};

我得到最上面的从该邮件。该解决方案还采用了适配器和政策,这似乎有点太多了,根据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>        ]
[...]

我在做什么错了?

有帮助吗?

解决方案

我怀疑你缺少你的do_compare static_visitor情况。 Remeber,变体可能有任何东西,所以你需要所有可能的组合,像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%它会工作,所以需要进行一些测试。除了清洁,更灵活的代码,它不应该有任何影响,只要它的作品。

scroll top