Warum werden die Sequenzoperationsalgorithmusprädikate von der Kopie übergeben?

15

Ich frage mich, warum Funktoren durch Kopieren an die algorithm Funktionen übergeben werden:

%Vor%

Ich habe folgende Ausgabe erwartet:

  

Die Summe von: 1; 1; 2; 3; 5; 8; 13; 21; 34; 55; ist: 143

Aber sum.result enthält 0 , das ist der Standardwert, der im ctor zugewiesen wurde. Die einzige Möglichkeit, das gewünschte Verhalten zu erzielen, ist die Erfassung des Rückgabewerts von for_each :

%Vor%

Dies passiert, weil der Funktor durch Kopie an die for_each weitergegeben wird, anstatt durch Referenz :

%Vor%

So bleibt der äußere Funktor unberührt, während der innere Funktor (der eine Kopie des äußeren ist) aktualisiert wird und nach dem Ausführen des Algorithmus ( live) zurückgegeben wird Demo ), so dass das Ergebnis nach allen Operationen wieder kopiert (oder verschoben) wird.

Es muss einen guten Grund geben, die Arbeit auf diese Weise zu machen, aber ich verstehe die Gründe in diesem Design nicht wirklich, deshalb sind meine Fragen:

  • Warum werden die Prädikate der Sequenzoperationsalgorithmen durch Kopie statt durch Referenz weitergegeben?
  • Welche Vorteile bietet der Pass-by-Copy-Ansatz vor dem Pass-by-Reference?
Paula_plus_plus 21.06.2013, 11:49
quelle

3 Antworten

6

Es ist hauptsächlich aus historischen Gründen. Im Jahr 1998, als das ganze Algo-Zeug es in die Standard-Referenzen geschafft hatte, gab es alle möglichen Probleme. Dies wurde schließlich durch Core und Library DRs von C ++ 03 und darüber hinaus gelöst. Auch sinnvolle Ref-Wrapper und eigentlich funktionierende Bindung kamen nur in TR1 an.

Diejenigen, die versucht haben, Algos mit früher C ++ 98 mit Funktionen zu verwenden, die ref-Parameter oder Returns verwenden, können sich an alle Arten von Problemen erinnern. Selbstgeschriebene Algos waren auch anfällig für das gefürchtete Problem "Verweis auf Referenz" .

Das Weiterreichen nach Wert hat zumindest gut funktioniert, und hat kaum Probleme verursacht - und Boost hatte schon früh Ref und Cref, um zu helfen, wo Sie zwicken mussten.

    
Balog Pal 21.06.2013, 11:57
quelle
4

Das ist reine Vermutung, aber ...

... lässt für einen Moment annehmen, dass es sich auf const bezieht. Dies würde bedeuten, dass alle Ihre Mitglieder veränderbar sein müssen und der Operator muss konstant sein. Das fühlt sich einfach nicht "richtig" an.

... lässt für einen Moment annehmen, dass es sich auf non-const bezieht. Es würde einen nichtkonstanten Operator aufrufen, Mitglieder können einfach gut bearbeitet werden. Was aber, wenn Sie ein Ad-hoc-Objekt übergeben möchten? Wie das Ergebnis einer Bindeoperation (sogar C ++ 98 hatte - hässliche und einfache - Bindewerkzeuge)? Oder der Typ selbst tut einfach alles, was Sie brauchen, und Sie brauchen das Objekt danach nicht mehr und wollen es einfach wie for_each(b,e,my_functor()); nennen? Das wird nicht funktionieren, da Provisorien nicht an nicht-konstante Referenzen binden können.

Also vielleicht nicht die beste, aber die schlechteste Option ist hier, um Wert zu nehmen, kopieren Sie es im Prozess so oft wie nötig (hoffentlich nicht zu oft) und dann, wenn Sie damit fertig sind, geben Sie es für for_each zurück. Dies funktioniert gut mit der relativ geringen Komplexität Ihres summierenden Objekts, erfordert keine zusätzlichen veränderbaren Dinge wie den Verweis auf const-Ansatz und arbeitet auch mit Provisorien.

Aber YMMV und wahrscheinlich auch die Mitglieder des Komitees, und ich vermute, es war am Ende eine Abstimmung darüber, was ihrer Meinung nach am ehesten zu den meisten Anwendungsfällen passt.

    
PlasmaHH 21.06.2013 12:26
quelle
1

Vielleicht könnte das ein Workaround sein. Erfassen Sie den Funktor als Referenz und rufen Sie ihn in einem Lambda

auf %Vor%     
Enigma 21.06.2013 12:03
quelle

Tags und Links