문제

동일한 유형의 객체를 저장하는 다른 유형의 반복자를 사용할 수있는 함수를 만들고 싶습니다.
첫 번째는 a입니다 std::map 포함 shared_ptr<Foo> (typedef-ed as FooMap) 그리고 다른 하나는 a 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;
}

Footerator와 방문자는 다음과 같이 정의됩니다.

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, 변형은 무엇이든 할 수 있으므로 바보 같은 :: const_iterator를 foomap :: const_iterator를 비교하는 것과 같은 모든 가능한 조합이 필요합니다. 컴파일러가 해당 케이스에 대해 일치를 찾으려고 노력하고 있으며 Foomap :: const_iterator를 바보 같은 :: 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; }

Comeau에서 컴파일하고 있지만 100% 작동하지 않으므로 일부 테스트가 필요합니다. 더 깨끗하고 다재다능한 코드 외에도 효과가없는 한 효과가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top