Можно ли хранить шаблонную лямбду в std :: function? - PullRequest
0 голосов
/ 03 октября 2019

с C ++ 20, мы получаем шаблонные лямбды для таких вещей:

    auto t = []<typename T>(T tmp){std::cout << tmp << std::endl;};

Но что если мне нужно указать точный тип через std :: function <>? (не полагайтесь на авто).

Можно ли сохранить шаблонную лямбду в оболочке std::function<>? например, похож на следующий?

    template<typename T>
    std::function<void(T)>  t = []<typename T>(T tmp){std::cout << tmp << std::endl;};

и использовать его как обычную функцию шаблона?

1 Ответ

3 голосов
/ 03 октября 2019

Есть проблема с шаблоном std::function. Это не один std::function, а много . Компилятор будет создавать все больше и больше глобальных данных, когда вы будете использовать больше типов.

Кроме того, вывод аргументов шаблона не будет работать, поскольку переменная std::function является шаблонной, а не operator() из std::function.

Кроме того, вам не нужен C ++ 20 для решения этой проблемы, попробуйте это с C ++ 14:

// equivalent to the templated lambda, just different syntax
auto t = [](auto tmp){std::cout << tmp << std::endl;};

Но что, если мне нужно указатьточный тип через std :: function <>? (не полагайтесь на авто).

Дело в том, что каждая лямбда имеет безымянный уникальный тип, который не может быть записан. auto - это only способ создания переменной лямбда-типа.

Используйте std::function только тогда, когда вам нужно стирание типа, когда вам нужна переменная неизвестного типа, но известнаяинтерфейс (например, operator()). std::function является несвободным и имеет время выполнения и двоичный размер стоимость. Это оболочка удаления типа для вызываемого типа.


А что если вам действительно нужен std::function?

Ну, std::function может работать только с известным типом. Например, это будет работать:

std::function<void(int)> t = []<typename T>(T arg) { /* ... */ }; 

, но будет вызывать только int версию лямбды.

Просить std::function иметь шаблонный operator() - это все равно что запрашиватьвиртуальная шаблонная функция. Он не может быть реализован.


Что если вы хотите использовать тип с известным именем?

Тогда не используйте лямбды! Они могут быть не тем инструментом, который вам нужен!

Вот эквивалент, не использующий ни auto, ни std::function:

struct MyLambda {
    template<typename T>
    auto operator()(T arg) { /* ... */ }
};

MyLambda my_function_returning_lambda() {
    // ...
}

// ...

MyLambda lambda = my_function_returning_lambda();

lambda(1);
lambda("works");
...