Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CPlusPlusNotesForProfessionals.pdf
Скачиваний:
47
Добавлен:
20.05.2023
Размер:
5.11 Mб
Скачать

lamb(20); //`a` becomes 20.

Generalize capture does not need to capture an external variable at all. It can capture an arbitrary expression:

auto lamb = [p = std::make_unique<T>(...)]()

{

p->SomeFunc();

}

This is useful for giving lambdas arbitrary values that they can hold and potentially modify, without having to declare them externally to the lambda. Of course, that is only useful if you do not intend to access those variables after the lambda has completed its work.

Section 73.11: Conversion to function pointer

If a lambda's capture list is empty, then the lambda has an implicit conversion to a function pointer that takes the same arguments and returns the same return type:

auto sorter = [](int lhs, int rhs) -> bool {return lhs < rhs;};

using func_ptr = bool(*)(int, int);

func_ptr sorter_func = sorter; // implicit conversion

Such a conversion may also be enforced using unary plus operator:

func_ptr sorter_func2 = +sorter; // enforce implicit conversion

Calling this function pointer behaves exactly like invoking operator() on the lambda. This function pointer is in no way reliant on the source lambda closure's existence. It therefore may outlive the lambda closure.

This feature is mainly useful for using lambdas with APIs that deal in function pointers, rather than C++ function objects.

Version ≥ C++14

Conversion to a function pointer is also possible for generic lambdas with an empty capture list. If necessary, template argument deduction will be used to select the correct specialization.

auto sorter = [](auto lhs, auto rhs) { return lhs < rhs; }; using func_ptr = bool(*)(int, int);

func_ptr sorter_func = sorter; // deduces int, int

//note however that the following is ambiguous

//func_ptr sorter_func2 = +sorter;

Section 73.12: Porting lambda functions to C++03 using functors

Lambda functions in C++ are syntactic sugar that provide a very concise syntax for writing functors. As such, equivalent functionality can be obtained in C++03 (albeit much more verbose) by converting the lambda function into a functor:

// Some dummy types: struct T1 {int dummy;}; struct T2 {int dummy;}; struct R {int dummy;};

GoalKicker.com – C++ Notes for Professionals

394

// Code using a lambda function (requires C++11) R use_lambda(T1 val, T2 ref) {

// Use auto because the type of the lambda is unknown. auto lambda = [val, &ref](int arg1, int arg2) -> R {

/* lambda-body */ return R();

};

return lambda(12, 27);

}

//The functor class (valid C++03)

//Similar to what the compiler generates for the lambda function. class Functor {

//Capture list.

T1 val;

T2& ref;

public:

// Constructor

inline Functor(T1 val, T2& ref) : val(val), ref(ref) {}

// Functor body

R operator()(int arg1, int arg2) const {

/* lambda-body */ return R();

}

};

//Equivalent to use_lambda, but uses a functor (valid C++03). R use_functor(T1 val, T2 ref) {

Functor functor(val, ref); return functor(12, 27);

}

//Make this a self-contained example.

int main() { T1 t1;

T2 t2; use_functor(t1,t2); use_lambda(t1,t2); return 0;

}

If the lambda function is mutable then make the functor's call-operator non-const, i.e.:

R operator()(int arg1, int arg2) /*non-const*/ {

/* lambda-body */ return R();

}

GoalKicker.com – C++ Notes for Professionals

395