Funktionsobjekt und for_each



  • Folgender Code wird von MinGW und BCC nicht kompiliert:

    #include <algorithm>
    #include <functional>
    #include <vector>
    
    using namespace std;
    
    struct transferitem_t
    {
        unsigned dst;
    
        transferitem_t (void) : dst (0) {}
    };
    
    std::vector <transferitem_t> ti (5);
    
    void doSomething (void)
    {
        class ConditionalAdd : public unary_function <void, transferitem_t&>
        {
        private:
            unsigned i, sz;
        public:
            ConditionalAdd (void)
            {}
            ConditionalAdd (unsigned i_, unsigned sz_)
             : i (i_), sz (sz_) {}
            ConditionalAdd (const ConditionalAdd& obj)
             : i (obj.i), sz (obj.sz) {}
            void operator () (transferitem_t& ti) const
            {
                if (ti.dst > i)
                    ti.dst += sz;
            }
        };
    
        for_each (ti.begin (), ti.end (), ConditionalAdd (1, 2));
    }
    

    Die Fehlermeldungen lauten:

    MinGW 3.4.2 schrieb:

    "main.cpp": main.cpp error: no matching function for call to `for_each(__gnu_cxx::__normal_iterator<transferitem_t*, std::vector<transferitem_t, std::allocator<transferitem_t> > >, __gnu_cxx::__normal_iterator<transferitem_t*, std::vector<transferitem_t, std::allocator<transferitem_t> > >, doSomething()::ConditionalAdd)' at line 35

    BCC 5.6.5 schrieb:

    "main.cpp": E2285 Could not find a match for 'for_each<_InputIter,_Function>(transferitem_t *,transferitem_t *,ConditionalAdd)' in function doSomething() at line 35

    BCC 5.82 schrieb:

    "main.cpp": E2285 Could not find a match for 'for_each<_InIt,_Fn1>(_Vector_iterator<transferitem_t,allocator<transferitem_t> >,_Vector_iterator<transferitem_t,allocator<transferitem_t> >,ConditionalAdd)' in function doSomething() at line 35

    Wenn ich in der entsprechenden Zeile die Template-Argumente explizit angebe, akzeptiert zumindest der BCC den Code, MinGW bringt den gleichen Fehler.

    for_each <std::vector <transferitem_t>::iterator, const ConditionalAdd&> (ti.begin (), ti.end (), ConditionalAdd (1, 2));
    

    Dabei müßte das doch auch ohne funktionieren, oder?
    Bitte sagt mir, daß ich nur irgendeine Kleinigkeit falsch mache 😞



  • Ich hätte auch gedacht, dass es gehen müsste. Es sieht so aus, als wäre es ein generelles Problem mit Function-Templates und Parametern in Form von Structs bzw. Klassen, die in Funktionen geschachtelt sind, denn folgender kleine Test löst den gleichen Kompilierfehler aus:

    template<typename T>
    void fubar(const T &nkrumah)
    {
    }
    
    void fu()
    {
        struct bar{};
        fubar(bar());
    }
    

    Ich wüsste gerne, was der Standard dazu sagt.



  • Der Standard sagt AFAIK dass das nicht geht.
    Typen die als Template Parameter hergenommen werden müssen "external linkage" haben.
    Lokale Klassen haben das nicht -> geht nicht.



  • OK, dann muß die Klassendefinition eben da raus. Danke für die Hilfe.



  • Du kannst übrigens nen "nameless namespace" nehmen damit die Klasse nicht mit anderen gleichnamigen (in anderen translation units) kollidiert.


Log in to reply