Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt Lambda reference
Qt 6.11 is out! See what's new in the release blog

Qt Lambda reference

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 3 Posters 1.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • SPlattenS Offline
    SPlattenS Offline
    SPlatten
    wrote on last edited by
    #1

    I have a Lambda slot:

    cnSignal = QObject::connect(this
                               ,&clsQtTextEdit::jsonTextChanged
                               ,[pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                   objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                   QString strJSON = clsXMLnode::strJSON(objJSON)
                                          ,strScriptWithCall = static_cast<QString>(strScript)
                                                                            + static_cast<QString>(strCall)
                                                                            + static_cast<QString>("(" + strJSON + ");");
                                   pobjScriptEng->evaluate(strScriptWithCall);
                               });
    

    I have multiple connections to different signals that all share the same Lambda function, is there any way to defined a local single instance of this and assign a reference or pointer to that instance instead of replication the same logic in multiple places?

    I'm thinking like a function pointer.

    Kind Regards,
    Sy

    JonBJ 1 Reply Last reply
    0
    • SPlattenS SPlatten

      @Bonnie , thank you, do you have an example on how to apply that technique to my example slot?

      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #5

      @SPlatten

      1. If you only want use that lambda in the current scope. I think auto is the best because it is very simple.
      auto func = [pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                     objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                     QString strJSON = clsXMLnode::strJSON(objJSON)
                                            ,strScriptWithCall = static_cast<QString>(strScript)
                                                                              + static_cast<QString>(strCall)
                                                                              + static_cast<QString>("(" + strJSON + ");");
                                     pobjScriptEng->evaluate(strScriptWithCall);
                                 };
      cnSignal = QObject::connect(this , &clsQtTextEdit::jsonTextChanged , func);
      
      1. But if you need to assign the lambda to a class member, then you need std::function because you cannot define an auto member variable.
      std::function<void(QJsonObject)> func = [pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                     objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                     QString strJSON = clsXMLnode::strJSON(objJSON)
                                            ,strScriptWithCall = static_cast<QString>(strScript)
                                                                              + static_cast<QString>(strCall)
                                                                              + static_cast<QString>("(" + strJSON + ");");
                                     pobjScriptEng->evaluate(strScriptWithCall);
                                 };
      cnSignal = QObject::connect(this , &clsQtTextEdit::jsonTextChanged , func);
      
      1 Reply Last reply
      2
      • SPlattenS SPlatten

        I have a Lambda slot:

        cnSignal = QObject::connect(this
                                   ,&clsQtTextEdit::jsonTextChanged
                                   ,[pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                       objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                       QString strJSON = clsXMLnode::strJSON(objJSON)
                                              ,strScriptWithCall = static_cast<QString>(strScript)
                                                                                + static_cast<QString>(strCall)
                                                                                + static_cast<QString>("(" + strJSON + ");");
                                       pobjScriptEng->evaluate(strScriptWithCall);
                                   });
        

        I have multiple connections to different signals that all share the same Lambda function, is there any way to defined a local single instance of this and assign a reference or pointer to that instance instead of replication the same logic in multiple places?

        I'm thinking like a function pointer.

        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by JonB
        #2

        @SPlatten
        I believe you are asking to be able to create & re-use a lambda "variable", right? I looked into this a couple of weeks ago. From what I read, C++ lambda object-variables are not so bad to write if they do not take any parameters. But if they do --- your QJsonObject objJSON --- then it's not so easy. If you persist with that, I read you must go via std::function() to do the job. An alternative suggestion was to move any parameters to the [...] context instead of passing as a function parameter.

        I gave up on it as being too much hassle. But I shall watch this question to see whether one of our resident C++ experts wants to show just how easily it can be done....

        1 Reply Last reply
        1
        • B Offline
          B Offline
          Bonnie
          wrote on last edited by Bonnie
          #3

          I think this is a C++11 question rather than a Qt one.
          The key points here are auto and std::function.
          You can refer to this example from https://en.cppreference.com/w/cpp/language/lambda :

          #include <vector>
          #include <iostream>
          #include <algorithm>
          #include <functional>
           
          int main()
          {
              std::vector<int> c = {1, 2, 3, 4, 5, 6, 7};
              int x = 5;
              c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());
           
              std::cout << "c: ";
              std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; });
              std::cout << '\n';
           
              // the type of a closure cannot be named, but can be inferred with auto
              // since C++14, lambda could own default arguments
              auto func1 = [](int i = 6) { return i + 4; };
              std::cout << "func1: " << func1() << '\n';
           
              // like all callable objects, closures can be captured in std::function
              // (this may incur unnecessary overhead)
              std::function<int(int)> func2 = [](int i) { return i + 4; };
              std::cout << "func2: " << func2(6) << '\n';
          }
          
          SPlattenS JonBJ 2 Replies Last reply
          4
          • B Bonnie

            I think this is a C++11 question rather than a Qt one.
            The key points here are auto and std::function.
            You can refer to this example from https://en.cppreference.com/w/cpp/language/lambda :

            #include <vector>
            #include <iostream>
            #include <algorithm>
            #include <functional>
             
            int main()
            {
                std::vector<int> c = {1, 2, 3, 4, 5, 6, 7};
                int x = 5;
                c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());
             
                std::cout << "c: ";
                std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; });
                std::cout << '\n';
             
                // the type of a closure cannot be named, but can be inferred with auto
                // since C++14, lambda could own default arguments
                auto func1 = [](int i = 6) { return i + 4; };
                std::cout << "func1: " << func1() << '\n';
             
                // like all callable objects, closures can be captured in std::function
                // (this may incur unnecessary overhead)
                std::function<int(int)> func2 = [](int i) { return i + 4; };
                std::cout << "func2: " << func2(6) << '\n';
            }
            
            SPlattenS Offline
            SPlattenS Offline
            SPlatten
            wrote on last edited by
            #4

            @Bonnie , thank you, do you have an example on how to apply that technique to my example slot?

            Kind Regards,
            Sy

            B 1 Reply Last reply
            0
            • SPlattenS SPlatten

              @Bonnie , thank you, do you have an example on how to apply that technique to my example slot?

              B Offline
              B Offline
              Bonnie
              wrote on last edited by Bonnie
              #5

              @SPlatten

              1. If you only want use that lambda in the current scope. I think auto is the best because it is very simple.
              auto func = [pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                             objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                             QString strJSON = clsXMLnode::strJSON(objJSON)
                                                    ,strScriptWithCall = static_cast<QString>(strScript)
                                                                                      + static_cast<QString>(strCall)
                                                                                      + static_cast<QString>("(" + strJSON + ");");
                                             pobjScriptEng->evaluate(strScriptWithCall);
                                         };
              cnSignal = QObject::connect(this , &clsQtTextEdit::jsonTextChanged , func);
              
              1. But if you need to assign the lambda to a class member, then you need std::function because you cannot define an auto member variable.
              std::function<void(QJsonObject)> func = [pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                                             objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                                             QString strJSON = clsXMLnode::strJSON(objJSON)
                                                    ,strScriptWithCall = static_cast<QString>(strScript)
                                                                                      + static_cast<QString>(strCall)
                                                                                      + static_cast<QString>("(" + strJSON + ");");
                                             pobjScriptEng->evaluate(strScriptWithCall);
                                         };
              cnSignal = QObject::connect(this , &clsQtTextEdit::jsonTextChanged , func);
              
              1 Reply Last reply
              2
              • SPlattenS Offline
                SPlattenS Offline
                SPlatten
                wrote on last edited by
                #6

                @Bonnie said in Qt Lambda reference:

                auto func = [pobjScriptEng, strCall, strFile, strScript, strSID](QJsonObject objJSON) {
                objJSON.insert(clsXMLnode::mscszAttrSubscriberID, strSID);
                QString strJSON = clsXMLnode::strJSON(objJSON)
                ,strScriptWithCall = static_cast<QString>(strScript)
                + static_cast<QString>(strCall)
                + static_cast<QString>("(" + strJSON + ");");
                pobjScriptEng->evaluate(strScriptWithCall);
                };

                Perfect, thank you!

                Kind Regards,
                Sy

                1 Reply Last reply
                0
                • B Bonnie

                  I think this is a C++11 question rather than a Qt one.
                  The key points here are auto and std::function.
                  You can refer to this example from https://en.cppreference.com/w/cpp/language/lambda :

                  #include <vector>
                  #include <iostream>
                  #include <algorithm>
                  #include <functional>
                   
                  int main()
                  {
                      std::vector<int> c = {1, 2, 3, 4, 5, 6, 7};
                      int x = 5;
                      c.erase(std::remove_if(c.begin(), c.end(), [x](int n) { return n < x; }), c.end());
                   
                      std::cout << "c: ";
                      std::for_each(c.begin(), c.end(), [](int i){ std::cout << i << ' '; });
                      std::cout << '\n';
                   
                      // the type of a closure cannot be named, but can be inferred with auto
                      // since C++14, lambda could own default arguments
                      auto func1 = [](int i = 6) { return i + 4; };
                      std::cout << "func1: " << func1() << '\n';
                   
                      // like all callable objects, closures can be captured in std::function
                      // (this may incur unnecessary overhead)
                      std::function<int(int)> func2 = [](int i) { return i + 4; };
                      std::cout << "func2: " << func2(6) << '\n';
                  }
                  
                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by
                  #7

                  @Bonnie
                  If I can chip in, now that OP seems happy.

                  So, you managed to do it even with parameters without having to use std::function(). I thought I read that was needed when I looked at SO posts, but perhaps that was older version of C++.

                  Armed with your answer, I just went back over code and did my lambda-to-be-used-many-times-in-one-function with your auto func1 = [](...) { return ...; }; and it wasn't so hard after all! So thanks very much for example.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved