Как работает общая лямбда в C ++ 14?

Как работает общая лямбда (auto ключевое слово как тип аргумента) в стандарте C ++ 14?

Основан ли он на шаблонах C ++, где для каждого отдельного аргумента тип компилятора генерирует новую функцию с тем же телом, но замененными типами (полиморфизм времени компиляции), или он больше похож на дженерики Java (стирание типов)?

Пример кода:

auto glambda = [](auto a) { return a; };

101

Решение

Общие лямбды были введены в C++14.

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

Итак, ваш пример:

auto glambda = [] (auto a) { return a; };

Сделаю glambda экземпляр этого типа:

class /* unnamed */
{
public:
template<typename T>
T operator () (T a) const { return a; }
};

В параграфе 5.1.2 / 5 стандарта C ++ 14 n3690 указано, как определяется оператор вызова для типа закрытия заданного лямбда-выражения:

Тип замыкания для неуниверсального лямбда-выражения имеет открытый оператор вызова встроенной функции (13.5.4)
чьи параметры и тип возвращаемого значения описываются параметром-объявлением-лямбда-выражения
и тип трейлинг-возврата соответственно. Для универсальной лямбды тип замыкания имеет открытый вызов встроенной функции
шаблон члена оператора (14.5.2), чей список-параметра-шаблона состоит из одного придуманного типа-параметра-шаблона
для каждого вхождения auto в предложении-объявления-параметра лямбды, в порядке появления
.
Шаблон-параметр изобретенного типа является пакетом параметров, если соответствующее объявление параметра объявляет
пакет параметров функции (8.3.5). Тип возвращаемого значения и параметры функции вызова функции
Шаблон оператора получен из условий конечного-возвращаемого типа и параметра-объявления лямбда-выражения
заменяя каждое вхождение auto в спецификаторах decl предложения параметра-объявлений на
имя соответствующего придуманного шаблона-параметра.

В заключение:

Это похоже на шаблоны, где для каждого другого типа аргумента компилятор генерирует функции с одинаковым телом, но с измененными типами, или это больше похоже на дженерики Java?

Как объясняет вышеприведенный абзац, универсальные лямбды — это просто синтаксический сахар для уникальных безымянных функторов с оператором шаблонного вызова. Это должно ответить на ваш вопрос 🙂

119

Другие решения

к несчастью, они не являются частью C ++ 11 (http://ideone.com/NsqYuq):

auto glambda = [](auto a) { return a; };

int main() {}

С g ++ 4.7:

prog.cpp:1:24: error: parameter declared ‘auto’
...

тем не мение, как это может быть реализовано в C ++ 14 в соответствии с Портлендское предложение для общих лямбд:

[](const& x, & y){ return x + y; }

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

struct anonymous
{
template <typename T, typename U>
auto operator()(T const& x, U& y) const -> decltype(x+y)
{ return x + y; }
};

Или согласно более новому предложению Предложение по общим (полиморфным) лямбда-выражениям

auto L = [](const auto& x, auto& y){ return x + y; };

--->

struct /* anonymous */
{
template <typename T, typename U>
auto operator()(const T& x, U& y) const // N3386 Return type deduction
{ return x + y; }
} L;

Так что да, для каждой перестановки параметров может возникать новая реализация, однако члены этого функтора все равно будут совместно использоваться (т.е. захваченные аргументы).

24

Это предложенная функция C ++ 14 (не в C ++ 11), аналогичная (или даже эквивалентная) шаблонам. Например, N3559 предоставляет этот пример:

Например, это общее лямбда-выражение, содержащее выражение:

auto L = [](const auto& x, auto& y){ return x + y; };

может привести к созданию типа замыкания и объекта, который ведет себя подобно структуре ниже:

struct /* anonymous */
{
template <typename T, typename U>
auto operator()(const T& x, U& y) const // N3386 Return type deduction
{ return x + y; }
} L;
14
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector