Лямбда-выражение в операторе return не может быть неявно преобразовано в функтор

#c

#c

Вопрос:

У меня есть следующий код

 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;};
}
 

Мои вопросы:

  1. Почему run1() это нормально, но run2() не разрешено?
  2. Есть ли в структуре конструктор Functor , который я могу определить, чтобы сделать run2() его действительным как есть? Я спрашиваю об этом, потому что в настоящее время возвращаемый тип run2() в моем проекте — std::function<void()> и все хорошо, но теперь мне нужно изменить его на функтор для хранения некоторых дополнительных свойств, но оператор return like run2() используется во многих местах, и я неохотно изменяю все его вхождения run1() .

Комментарии:

1. Допускается только одно неявное пользовательское преобразование. run2 требуется 2 (лямбда-> std::function -> Functor ).

2. Как насчет превращения вашего Functor конструктора в шаблон? template<class F> Functor(Famp;amp; task) : _task(std::forward<F>(task)) {}

Ответ №1:

  1. Как уже упоминалось в комментариях, run2 требует двух неявных пользовательских преобразований, что запрещено.
  2. Вы можете создать конструктор шаблонов Functor , чтобы сделать ваш код допустимым:
 #include <functional>
#include <iostream>

struct Functor {
    Functor(auto amp;amp; 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;};
}

 

Демонстрация: https://gcc.godbolt.org/z/bdnYTbKv4