Frage zu Lambda-Captures [Erledigt]



  • Hallo,
    wir compilieren unseren Code mit dem GCC und ich habe ihn mal testweise mit clang kompiliert.
    Wir haben eine Funktion in dieser Art:

    #include <tuple>
    #include <string>
    #include <iostream>
    
    std::tuple<std::string, std::string> getStrings() {
        return { "Hello ", "World" };
    }
    
    int main() {
    
        const auto [str1, str2] = getStrings();
    
        auto lambda = [str1, str2]() {
            std::cout << str1 << str2;
        };
    
        lambda();
    
        return 0;
    }
    

    Wenn man nun versucht str1 und str2 in einem Lambda zu capturen, gibt Clang 10 folgenden Fehler zurück:

    str1 in capture list does not name a variable
    str2 capture list does not name a variable
    

    Bzw. Clang 12 sagt:

    error: reference to local binding 'str1' declared in enclosing function 'main'x86-64 clang 12.0.0 #1
    error: reference to local binding 'str2' declared in enclosing function 'main'x86-64 clang 12.0.0 #1
    

    Ändere ich den Code folgendermaßen, funktioniert das:

    const auto strings = getStrings();
    
    std::string str1 = std::get<0>(strings);
    std::string str2 = std::get<1>(strings);
    

    Nun ist es aber so, dass der Standard sagt:

    "The type of each data member is the type of the corresponding captured entity, except if the entity has reference type (in that case, references to functions are captured as lvalue references to the referenced functions, and references to objects are captured as copies of the referenced objects)."

    Wie kann das also sein, dass sich hier Clang verweigert das zu kompilieren?

    Danke im Voraus!



  • Siehe https://stackoverflow.com/questions/46114214/lambda-implicit-capture-fails-with-variable-declared-from-structured-binding und https://en.cppreference.com/w/cpp/language/structured_binding: "Structured bindings cannot be captured by lambda expressions. (until C++20)"

    Offenbar ist in clang die Änderung noch nicht drin, dass das inzwischen möglich ist. Der Grund ist wohl, wenn ich das richtig überflogen habe, dass die Structured Binding nur Namen, aber nicht Variablen einführt und dass ein Lambda nur Variablen capturen konnte.



  • @wob Puh, das ist ja heftig! Ein User schreibt dort, dass das ein Bug im Standard ist. Also warten bis wir C++ 20 nutzen...
    Danke für deine Mühe! 🙂


Anmelden zum Antworten