Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Return type of lambda function



  • Hi All,

    auto x1 = [](int i) { return i; };
    cout << typeid(x1).name();
    

    The output for type x1 is class <lambda_8cff3db0c4e5c934a92a739779c1aa4d> . I was expecting the type deduced for x1 to be int.

    Can someone help me with the following points,

    • why the type deduced is class <lambda_8cff3db0c4e5c934a92a739779c1aa4d> ?

    • How to make lambda to return int?

    I am using MSVC Compiler.



  • @Vinoth-Rajendran4
    I just think your expectation is wrong! x1 is the lambda itself, hence the output. You are confusing that with what will be returned when the lambda is executed, which is a totally different thing. Your lambda will return an int when executed, so you're all done, what makes you think there is any issue?

    I am not a C++ expert, but if you like you can specify the lambda return type via

    auto x1 = [](int i) -> int { return i; };
    

    but I don't think you have to/will make any difference here (you have just a simple return statement in it).



  • @JonB , Thanks for the update.. I got the point.



  • I cannot remember everything I was doing here, but I was testing if getting the return type would invoke the lambda. I think it will not and it will give you the return type. You will have to search online the other crap I was testing here as I don't remember:

        {
            auto func = [](int a){
                qInfo() << "Invoked";
                return a;
            };
            auto a = func(1);
            qInfo() << typeid(a).name();
            decltype (a) b;
            qInfo() << typeid(b).name();
            qInfo() << typeid(func(1)).name();
        }
    

    Types returned by typeid are compiler specific if I remember correctly. So it would not be suitable for cross platform code unless you can ensure the same compiler everywhere.


  • Qt Champions 2017

    There's std::invoke_result for that purpose. It goes like this (more or less):

    auto x1 = [](int i) -> int { return i; };
    
    typedef typename std::invoke_result<decltype(x1), int>::type x1ret_type; //< which is int
    


  • This is interesting:

       {
            auto x1 = [](int i) -> int {
                qInfo() << "Invoked";
                return i;
            };
    
            typedef typename std::invoke_result<decltype(x1), int>::type x1ret_type;
            typedef decltype (x1(1)) rtype;
    
            Q_ASSERT(typeid(rtype) == typeid(x1ret_type));
            qInfo() << typeid(rtype).name() << typeid(x1ret_type).name();
        }
    

  • Qt Champions 2017

    @fcarney said in Return type of lambda function:

    This is interesting:

    What is?



  • I didn't know if decltype would not execute the function to get the return type. I was playing with it. I knew typeid did, didn't know about decltype. So the two methods produce the same output.


  • Qt Champions 2017

    @fcarney said in Return type of lambda function:

    I didn't know if decltype would not execute the function to get the return type.

    It would if it could but it can't so it shan't. decltype is evaluated at compile time, so there's no way it could or would execute a function (unless the function is also evaluated at compile time, which it isn't here). On the other hand typeid is a runtime-executed operator.



  • @kshegunov Just to be clear, I think I was not clear, typeid does NOT execute the function to find the return type either. I think I said it strangely.


  • Qt Champions 2017

    @fcarney said in Return type of lambda function:

    @kshegunov Just to be clear, I think I was not clear, typeid does NOT execute the function to find the return type either. I think I said it strangely.

    Are you sure? That'd be odd.



  •     {
            auto x1 = [](int i) -> int {
                qInfo() << "Invoked";
                return i;
            };
    
            typedef typename std::invoke_result<decltype(x1), int>::type x1ret_type;
            typedef decltype (x1(1)) rtype;
    
            Q_ASSERT(typeid(rtype) == typeid(x1ret_type));
            qInfo() << typeid(rtype).name() << typeid(x1ret_type).name();
    
            qInfo() << "before typeid";
            typeid(x1(1));
            qInfo() << "after typeid";
    
        }
    

    Pretty sure, I saw this behavior before (tested again):

    i i
    before typeid
    after typeid
    

Log in to reply