webForumDet fria alternativet

for_each fråga

7 svar · 176 visningar · startad av Sang-drax

Sang-draxMedlem sedan juli 2002581 inlägg
#1

Standard-funktionen for_each ser ut ungefär så här:

template<class Iter, class FuncType>
  inline FuncType for_each(Iter First, Iter Last, FuncType Func)
  {	
    for (; First != Last; ++First)
    Func(*First);
    return (Func);
  }

Men vore det inte bättre om såg ut så här?

template<class Iter, class FuncType>
  inline FuncType for_each(Iter First, Iter Last, FuncType[B]&[/B]  Func)
    //samma i övrigt

Alltså den sista parametern skickas som referens.
Det gör denna kod möjlig:

struct Sum
{
    Sum(){sm = 0;}
    void operator() (int s){sm += s;}
    int sm;
};

int main()
{
    vector<int> v;
    v.push_back(2);
    v.push_back(5);
    v.push_back(9);
    Sum s;
    for_each(v.begin(),v.end(),s);
    cout << s.sm;
}
FridolfMedlem sedan aug. 2001723 inlägg
#2

Behövs inte, funkar ändå... några små tillägg bara...

struct Sum [b]: public unary_function<int, void>[/b]
{
    Sum(){sm = 0;}
    void operator() (int s){sm += s;}
    int sm;
};

int main()
{
    vector<int> v;
    v.push_back(2);
    v.push_back(5);
    v.push_back(9);
    Sum s [b]=[/b] for_each(v.begin(),v.end(),[b]Sum()[/b]);
    cout << s.sm;
}

Vet inte om ändringarna är absolut nödvändiga, kan inte testa det just nu. Kolla om det funkar.

Sang-draxMedlem sedan juli 2002581 inlägg
#3

Det var inte så jag menade.
Att härleda från unary_function är onödigt.

Det räcker i mitt exempel att skriva:

Sum s = for_each(v.begin(),v.end(),s);

Men jag vill liksom slippa = tecknet.
Lite snyggare kod om man ska ha summan av många listor, och jag har även fått för mig att det går lite snabbare.

Men: Finns det några argument för att inte ha referens?

FridolfMedlem sedan aug. 2001723 inlägg
#4

OK... nej i så fall kommer jag inte på någon bra anledning att inte ha referens.

BeatboxMedlem sedan okt. 20013 217 inlägg
#5

För att öka läsbarheten koden eftersom man ser inte vid anropet av for_each att argumentet tas mot som refferens. Det är vad jag tror i alla fall.

Sang-draxMedlem sedan juli 2002581 inlägg
#6

Jag antar att en hyfsad kompilator optimerar bort det temporära objektet som annars borde skapas.

Det får jag ta och testa.

Sang-draxMedlem sedan juli 2002581 inlägg
#7

... Jupp det gör den, det var ju skönt iaf.

Sang-draxMedlem sedan juli 2002581 inlägg
#8

Hehe, jag kom på en lösning :D

template<class C>
    class for_each_wrapper
    {
    public:
        for_each_wrapper(C& __c) {c = &__c;}
        template<typename T>
            void operator()(T t) {(*c)(t);}
    private:
        C* c;
    };

template<class C>
    for_each_wrapper<C> ref(C& c)
    {
        return for_each_wrapper<C>(c);
    }

//Då anropas for_each så här:
for_each(v.begin(),v.end(),ref(s));

Äntligen slapp man det där förhatliga = tecknet!

124 ms totalt · 3 externa anrop · v20260731065814-full.30151723
0 ms — hämta forumlista (cache)
0 ms — hämta statistik (cache)
122 ms — hämta tråd, inlägg och bilagor (db)