2016-08-09 69 views
10

I 6.1 das folgende Programm mit gcc nicht kompilieren können:gcc nicht generic Lambda mit dieser Aufnahme kompilieren

#include <iostream> 
#include <string> 
#include <vector> 
#include <iterator> 
#include <algorithm> 

class Foo 
{ 
public: 
    void apply() const 
    { 
     std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { print(x); }); 
    } 
private: 
    std::vector<std::string> bars_; 

    void print(const std::string& x) const 
    { 
     std::cout << x << ' '; 
    } 
}; 

int main() 
{ 
    Foo foo {}; 
    foo.apply(); 
    return 0; 
} 

Die Fehlermeldung lautet:

error: cannot call member function 'void Foo::print(const string&) const' without object 
     std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { print(x); }); 
                         ^~~~~ 
  • Ändern const auto& x-const std::string& x das macht Programm kompilieren.

  • Durch die Änderung print(x) zu this->print(x) wird das Programm kompiliert.

  • Alle Versionen kompilieren mit Clang (Apple LLVM Version 7.3.0 (clang-703.0.31)).

Ist das ein Compilerfehler?

+0

Könnte das nicht sein, weil ein generisches Lambda nur eine 'Template'-Funktion ist, die vorgibt, keine' Template'-Funktion zu sein, und Sie müssen 'this->' ähnlich in echten Template-Funktionen qualifizieren? IIRC ... –

+2

@underscore_d Das ist für abhängige Basen. –

+5

clang kompiliert es, vielleicht ist es gcc Bug, siehe hier: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61636 – marcinj

Antwort

-3

Ich glaube nicht, dass der Compiler den Typ ableiten muss, der an das Lambda innerhalb der for_each-Funktion übergeben wird. Denken Sie daran, dass diese Funktion bereits kompiliert wurde. Wie kann der Compiler wissen, was die for_each-Funktion passieren wird zum Lambda, nachdem es das Lambda hereingelassen hat?

+0

Nun, es wurde nicht kompiliert, weil es einen Fehler gibt, der die Kompilierung blockiert. Aber ich verstehe, worauf du hinaus willst. Da das dritte Argument jedes aufrufbar sein kann, schien es mir, und ich denke Sie, dass sein Argument von den Eingabe-Iteratoren ableitbar sein könnte, aber der Rest seines Typs konnte nicht. Dies scheint jedoch eine Einschränkung unseres Verständnisses zu sein, da 'clang' es akzeptiert und der verlinkte Bugzilla impliziert, dass es sich um einen gültigen Fall handelt, der in dem' g ++ 'Parser mit Mehrdeutigkeit behaftet ist. –

+0

Sorry, ich meine, die for_each-Funktion wurde bereits kompiliert. –

+1

Es sieht sicherlich wie ein Fehler aus, der Fehler Fehler: kann Memberfunktion 'void Foo :: print (const String &) const' ohne Objekt nicht aufrufen bedeutet, dass es den Parametertyp –

-4

Ich weiß nicht warum. Die Lösung besteht darin, anzugeben, welchen Druck es verwenden soll: std::for_each(std::cbegin(bars_), std::cend(bars_), [this] (const auto& x) { this->print(x); });

Mit diesem kompiliert es. Siehe: http://coliru.stacked-crooked.com/a/1177b09a3e5863e2

+3

Dies ist keine Antwort. Die Frage besagt bereits explizit, dass das Hinzufügen von 'this->' dies kompiliert. – lisyarus

+0

als auf http://stackoverflow.com/questions/11284059/call-method-inside-lambda-expression oder http://stackoverflow.com/questions/4940259/lambdas-require-capturing-this-to-call- static-member-function – frank

+3

Dies ist immer noch irrelevant. Der Code in der Frage erfasst "this" bereits explizit. – lisyarus

5

Dies ist eine dokumentierte gcc bug, die seit August 2016 noch nicht behoben wurde.