Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda in return statement cannot be implicitly converted to functor

Tags:

c++

I have the following code

struct Functor
{
    Functor(std::function<void()> task) : _task {task} {}
    void operator() () {_task();}
    std::function<void()> _task{};
};

Functor run1() //OK
{
    return Functor([](){std::cout << "From function" << std::endl;});
}

Functor run2() //Bad. Compile time error
{
    return [](){std::cout << "From function" << std::endl;};
}

My questions are:

  1. Why run1() is okay but run2() is not allowed?
  2. Is there a constructor in the struct Functor that I can define in order to make run2() valid as it is? I am asking this because currently the return type of run2() in my project is std::function<void()> and all is good, but I now need to change it into a functor to store some additional properties, but return statement like run2() are used in many places, and I am reluctant to modify every occurrences of it into run1().
like image 413
RelativisticPenguin Avatar asked Dec 07 '21 16:12

RelativisticPenguin


People also ask

How do you return from a lambda function?

The characteristics of lambda functions are: Lambda functions are syntactically restricted to return a single expression. You can use them as an anonymous function inside other functions. The lambda functions do not need a return statement, they always return a single expression.

Can you return from a lambda C++?

The return type for a lambda is specified using a C++ feature named 'trailing return type'. This specification is optional. Without the trailing return type, the return type of the underlying function is effectively 'auto', and it is deduced from the type of the expressions in the body's return statements.

Which of the following statement is true about lambda expression?

What is the correct statement about lambda expression? Explanation: Return type in lambda expression can be ignored in some cases as the compiler will itself figure that out but not in all cases. Lambda expression is used to define small functions, not large functions.

What is the return type of lambda expression?

What is the return type of lambda expression? Explanation: Lambda expression enables us to pass functionality as an argument to another method, such as what action should be taken when someone clicks a button.


1 Answers

  1. As it is already mentioned in the comments, run2 requires two implicit user conversions, which is prohibited.

  2. You can create a template constructor in Functor to make your code valid:

#include <functional>
#include <iostream>

struct Functor {
    Functor(auto && task) : _task { task } {}
    void operator() () {_task();}
    std::function<void()> _task{};
};

Functor run1() //OK
{
    return Functor([](){std::cout << "From function" << std::endl;});
}

Functor run2() //Ok
{
    return [](){std::cout << "From function" << std::endl;};
}

Demo: https://gcc.godbolt.org/z/bdnYTbKv4

like image 113
Fedor Avatar answered Oct 23 '22 07:10

Fedor