- Forward


Lambda Expressions
An Introduction with Examples in C++


Prof. David Bernstein
James Madison University

Computer Science Department
bernstdh@jmu.edu

Print

Motivation
Back SMYC Forward
  • A Common Need:
    • Passing a function pointer to a method/function
  • Examples:
    • Passing a comparator (i.e., a method of comparing values) to a sorting method/function
    • Passing a filter to an output method/function
  • A Less-Common Need (Satisfied by Lambda Expressions):
    • Passing an anonymous (i.e., un-named) function
Syntax
Back SMYC Forward
  • Syntax of the Expression:
    • [] () mutable throw() -> type
  • Explanation:
    • [] is the capture clause (a.k.a., lambda introducer) that contains the variables to access from the surrounding scope
    • () is the optional parameter list (a.k.a, lambda declarator)
    • mutable is the optional modifier that allows the lambda to modify captured values
    • throw() is the exception specification
    • type is the return type
  • Syntax of the Capture Clause:
    • [identifier] capture identifier by value (where multiple identifiers are delimited by a comma)
    • [&identifier] capture identifier by reference (where multiple identifiers are delimited by a comma)
    • [=] capture all external variables by value
    • [&] capture all external variables by reference
The Type of a Lambda Expression
Back SMYC Forward
  • The Callable Type:
    • A type for which the INVOKE operation is applicable
  • A Convenient Wrapper:
    • std::function in <functional>
The Type of a Lambda Expression (cont.)
Back SMYC Forward
  • Definition of std::function:
    • template < class R, class... Args >
      class function<R(Args...)>;
  • Explanation:
    • R denotes the type of the result
    • Args denotes the arguments
An Example
Back SMYC Forward
  • The Setting:
    • We want to find the closest destination to a particular origin
  • The Need for a Lambda Expression:
    • There are many different ways to calculate the distance
An Example (cont.)
Back SMYC Forward

The closest() Function

cppexamples/lambdas/VectorMathExample.cpp (Fragment: closest)
 

Note: This function is passed the origin, the destinations, the number of destinations, and the std::function to use to calculate the distance.

An Example (cont.)
Back SMYC Forward

One Invocation of closest()

cppexamples/lambdas/VectorMathExample.cpp (Fragment: Euclidean)
 
An Example (cont.)
Back SMYC Forward

Another Invocation of closest()

cppexamples/lambdas/VectorMathExample.cpp (Fragment: rectilinear)
 
Another Example
Back SMYC Forward
  • The Setting:
    • A unit testing framework/harness
  • The Need for a Lambda Expression:
    • Pass a block of code that should throw an exception
Another Example (cont.)
Back SMYC Forward

The assertThrows() Function

/** * Check to see if a lambda expression throws a particular exception. * * @tparam T The class of the exception * @param lambda The lambda expression to execute * @throws invalid_argument if the exception is not thrown */ template<class T> void assertThrows(std::function<void ()> lambda) { bool doesThrow = false; try { lambda(); } catch(const exception& e) { doesThrow = dynamic_cast<const T*>(&e) != nullptr; } if (!doesThrow) { throw(invalid_argument("Expected " + string(typeid(T).name()) + " to be thrown")); } }
Another Example (cont.)
Back SMYC Forward

The Unit Test

try { assertThrows<out_of_range>([](void) { Sequence seq = {3,4,6}; seq.get(-1); }); } catch (const invalid_argument& ia) { printf("Failed test: %s\n", ia.what()); }
There's Always More to Learn
Back -