Следующий код пытается создать шаблонную лямбду и передать ее вызывающей ее функции. Однако компиляция завершается неудачно, поскольку тип аргумента lambda
неправильный.
#include <functional>
void foo(std::function<void(void)>&lambda) {
lambda.template operator()<int>();
}
int main() {
auto f = []<class T>() {};
foo(f);
}
Как мне определить тип аргумента, который получает шаблонную лямбду?
Использование auto
работает, но мне нужен явный тип (чтобы я мог изменить foo
, чтобы он возвращал все, что возвращает лямбда).
void foo(auto &lambda) { // Works but not what I want
Я пробовал это, но не компилируется:
template<class T>
void foo(std::function<void<T>(void)>&lambda) {
Разница между тем, что вы называете шаблонной лямбдой, и обычной лямбдой заключается в том, что operator()
является шаблоном. В остальном особой разницы между типом самой лямбды нет. Это уникальный безымянный тип.
Как мне определить тип аргумента, который получает шаблонную лямбду?
То же, что и для нешаблонной лямбды.
... но мне нужен явный тип (чтобы я мог изменить foo, чтобы он возвращал все, что возвращает лямбда).
Для этого вам не нужно знать тип лямбды, потому что вы можете использовать возвращаемый тип auto
:
auto foo(auto &lambda) {
auto ret = lambda.template operator()<int>();
return ret;
}
Тип лямбды — decltype(lambda)
, а возвращаемый тип operator()
при создании экземпляра с помощью int
— decltype(lambda.operator()<int>())
(при необходимости добавьте std::decay_t
).
PS: std::function
, как правило, не тот тип, который следует использовать всегда при передаче вызываемого объекта в функцию. std::function
предназначен в первую очередь для стирания текста, которое здесь вам не нужно. Если вы используете его просто для удобства, то однажды вы почувствуете себя преданным из-за цены, которую вы платите за то, чем не пользуетесь.
«Однажды ты почувствуешь себя преданным за цену, которую заплатишь», как сегодня, когда шаблон был стерт operator()
std::function<void(void)>
не является лямбдой и не имеет шаблонаoperator()
, подпись закреплена заvoid(void)
.