"لا يمكن تحويل المعلمة" باستخدام دفعة :: اختبار المتغير

StackOverflow https://stackoverflow.com/questions/970382

سؤال

أريد إنشاء وظيفة يمكن أن تتخذ أنواعا مختلفة من المحفون الذين يخزنون نفس النوع من الكائن:
الأول هو 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;
}

يتم تعريف Foo Niterator والزائرين على النحو التالي:

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; }
};

حصلت على معظم ما سبق من مرفق هذا البريد. وبعد يستخدم هذا الحل أيضا محولات وسياسات، والتي يبدو أنها أكثر من اللازم قليلا، وفقا لإجابة رسائن الملابس، لذلك لا أرغب في نسخ هذا الرمز ببساطة. خاصة وأنا أفهم جزء منه فقط.

مع الرمز أعلاه، أحصل على خطأ مترجم أعلاه من 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 إلى FOOD_AT_ATITATOR.

ضربها:

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٪ ستعمل، لذلك مطلوب بعض الاختبارات. بخلاف Cleaner، رمز أكثر تنوعا، لا ينبغي أن يكون لها أي تأثير، طالما أنه يعمل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top