Как вызвать лямбда-шаблон? - PullRequest
4 голосов
/ 24 июня 2019

Мне удалось скомпилировать следующий код с помощью gcc:

template<typename... Pack>
auto func(Pack... x) {
    return (x + ...) ;
}

template<typename... Pack>
auto lamd = [](Pack... x) {
    return (x + ...) ;
};

Я могу вызвать шаблон функции с помощью func(1,2,3), но я получаю ошибку при вызове лямбда-выражения с lamd(1,2,3) илиlamd<int>(1,2,3).

Ответы [ 3 ]

4 голосов
/ 24 июня 2019

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

auto lamd = [](auto... x) {
    return (x + ...) ;
};

Начиная с C ++ 20 вы можете использовать явный список параметров шаблона, нообратите внимание, что список параметров шаблона по-прежнему используется с operator() лямбды, так же как и с использованием auto параметров.например,

auto lamd = []<typename... Pack>(Pack... x) {
    return (x + ...) ;
};

, а затем вы можете назвать его как lamd(1,2,3).

LIVE

3 голосов
/ 24 июня 2019

Второе определение - это шаблон переменной. Он не определяет лямбду operator() как шаблон, а принимает пакет параметров для типов аргументов operator(). Результирующий operator() является обычной функцией-членом типа замыкания инстанцированной переменной. Здесь невозможно вывести аргументы шаблона.

Таким образом, когда вы пишете lamd<int>, переменная получает тип замыкания с operator()(int), а не что-то вызываемое с 3 целыми числами.

Как уже упоминалось, вместо этого вы можете использовать общую лямбду.

В C ++ 20, если вам нужно, чтобы лямбда-типы аргументов были названы и выведены, вы можете использовать синтаксис:

auto lamd = []<typename... Pack>(Pack...) {}

определит оператора как шаблон, принимая пакет параметров, и оставит дверь открытой для вывода аргумента шаблона.

3 голосов
/ 24 июня 2019

Лямбда-шаблон не существует. Лямбда-выражение всегда имеет уникальный, новый тип. В частности, это не шаблон, который можно использовать для создания экземпляров реальных функций.

Оператор вызова функции, предоставляемый lamdba, может быть шаблоном. И вы получите бесплатный синтаксис:

auto lamd = [](auto... x) {
    return (x + ...) ;
};

Обратите внимание, что C ++ 2a будет поставляться с дополнительной поддержкой и явностью для общих лямбд и позволяет вам

auto lambda = []<typename...T>(T&& ...args) { /* ... */ };

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...