Übergabe von Lambda, deklariert mit Auto-Schlüsselwort durch nichtkonstante Referenz als Argument für std :: function Parametertyp

8

Betrachten Sie den folgenden Code:

%Vor%

Würde mir jemand erklären:

(a) Warum generiert fizz(g2) einen Kompilierfehler und die anderen Konstrukte nicht? Es scheint, dass ich ein Lambda per Referenz übergeben kann, wenn ich seinen Typ explizit in seiner Deklaration eingabe, aber nicht, wenn ich das Schlüsselwort auto verwende, ODER wenn ich den Funktionsparameter Typ als const deklariere.

(b) Was const im Funktionsparameter-Typ bedeutet hier?

(c) Unter welchen Umständen würde ich lieber nach Wert als nach Referenz gehen (UPDATE: Jetzt eine separate Frage: C ++ 11: übergeben (Lambda oder andere) Funktion Objekt durch Referenz oder Wert? )?

Danke für jede Einsicht.

    
Jeet 13.04.2013, 05:04
quelle

1 Antwort

9

In Ihrem Fall fizz(g1) ist g1 bereits ein std::function . Daher ist eine implizite Konvertierung nicht erforderlich. Der Parameter fizz ist also ein nicht-konstanter Verweis auf g1 .

In fizz(g2) , g2 ist nicht a std::function . Daher muss der Compiler eine implizite Konvertierung durchführen. Und die implizite Konvertierung gibt ein temporäres zurück.

Temporäre Objekte können nicht an nicht-konstante Referenzen gebunden werden; Sie können nur an const Referenzen oder Werte binden. Daher der Compilerfehler.

  

Was bedeutet const im Funktionsparameter-Typ hier?

Sie können nur const -Member des Objekts aufrufen, Sie können es nicht implizit in non const konvertieren, und Sie können nicht const -Operationen für seine Member ausführen.

Sie wissen, genau wie jede andere Verwendung von const .

Wenn eine Funktion einen Parameter mit einer nichtkonstanten Referenz verwendet, sagt sie etwas ganz Besonderes darüber aus, was sie mit diesem Parameter zu tun beabsichtigt. Nämlich, dass Sie ihm ein Objekt übergeben, und es wird nichtkonstante Dinge damit machen (dh: dieses Objekt modifizieren). Aus diesem Grund binden Provisorien nicht an nicht-konstante Referenzen. Es ist wahrscheinlich ein Fehler des Benutzers, da das temporäre Objekt das übergebene Originalobjekt möglicherweise nicht aktualisiert.

Wenn fizz das Objekt tatsächlich ändert, sollten Sie es entweder nach Wert oder nach const& übergeben.

    
Nicol Bolas 13.04.2013, 05:36
quelle

Tags und Links