#include<functional>
#include<iostream>
std::function<int(int, int)> returnLambda()
{
return [](int x, int y) {
return x*y;
};
}
int main()
{
auto lf = returnLambda();
std::cout << lf(6, 7) << std::endl;
}
输出结果:42
lambda 与 bind对比
#include <functional>
#include <iostream>
int main()
{
auto plus10 = std::bind(std::plus<int>(),
std::placeholders::_1,
10);
std::cout << "+10: " << plus10(7) << std::endl;
auto plus10times2 = std::bind(std::multiplies<int>(),
std::bind(std::plus<int>(),
std::placeholders::_1,
10),
2);
std::cout << "+10 *2: " << plus10times2(7) << std::endl;
auto pow3 = std::bind(std::multiplies<int>(),
std::bind(std::multiplies<int>(),
std::placeholders::_1,
std::placeholders::_1),
std::placeholders::_1);
std::cout << "x*x*x: " << pow3(7) << std::endl;
auto inversDivide = std::bind(std::divides<double>(),
std::placeholders::_2,
std::placeholders::_1);
std::cout << "invdiv: " << inversDivide(49, 7) << std::endl;
}
#include <iostream>
int main()
{
auto plus10 = [](int i) {
return i + 10;
};
std::cout << "+10: " << plus10(7) << std::endl;
auto plus10times2 = [](int i) {
return (i + 10) * 2;
};
std::cout << "+10 *2: " << plus10times2(7) << std::endl;
auto pow3 = [](int i) {
return i*i*i;
};
std::cout << "x*x*x: " << pow3(7) << std::endl;
auto inversDivide = [](double d1, double d2) {
return d2 / d1;
};
std::cout << "invdiv: " << inversDivide(49, 7) << std::endl;
}
lambda与function objects
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// function object to process the mean value
class MeanValue {
private:
long num; // number of elements
long sum; // sum of all element values
public:
// constructor
MeanValue () : num(0), sum(0) {
}
// "function call"
// - process one more element of the sequence
void operator() (int elem) {
++num; // increment count
sum += elem; // add value
}
// return mean value
double value () {
return static_cast<double>(sum) / static_cast<double>(num);
}
};
int main()
{
vector<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8 };
// process and print mean value
MeanValue mv = for_each (coll.begin(), coll.end(), // range
MeanValue()); // operation //for_each() has the unique ability to return its function object
cout << "mean value: " << mv.value() << endl;
}
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main()
{
vector<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8 };
// process and print mean value
long sum = 0;
for_each(coll.begin(), coll.end(), // range
[&sum](int elem) {
sum += elem;
});
double mv = static_cast<double>(sum) / static_cast<double>(coll.size());
cout << "mean value: " << mv << endl;
}
lambda与stateful function objects
#include <iostream>
#include <list>
#include <algorithm>
#include "print.hpp"
using namespace std;
class Nth { // function object that returns true for the nth call
private:
int nth; // call for which to return true
int count; // call counter
public:
Nth (int n) : nth(n), count(0) {
}
bool operator() (int) {
return ++count == nth;
}
};
int main()
{
list<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
PRINT_ELEMENTS(coll,"coll: ");
// remove third element
list<int>::iterator pos;
pos = remove_if(coll.begin(),coll.end(), // range
Nth(3)); // remove criterion
coll.erase(pos,coll.end());
PRINT_ELEMENTS(coll,"3rd removed: ");
}
输出结果:
coll: 1 2 3 4 5 6 7 8 9 10
3rd removed: 1 2 4 5 7 8 9 10
#include <iostream>
#include <list>
#include <algorithm>
#include "print.hpp"
using namespace std;
int main()
{
list<int> coll = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
PRINT_ELEMENTS(coll,"coll: ");
// remove third element
list<int>::iterator pos;
int count=0; // call counter
pos = remove_if(coll.begin(),coll.end(), // range
[count] (int) mutable { // remove criterion
return ++count == 3;
});
coll.erase(pos,coll.end());
PRINT_ELEMENTS(coll,"3rd removed: ");
}
coll: 1 2 3 4 5 6 7 8 9 10
3rd removed: 1 2 4 5 7 8 9 10
If you pass the argument by reference and don’t use mutable, the behavior is as expected,
because both lambda objects internally used by remove_if() share the same state. Thus, with
the following:
int count=0; // call counter
pos = remove_if(coll.begin(),coll.end(), // range
[&count] (int) { // remove criterion
return ++count == 3;
});
the output is:
coll: 1 2 3 4 5 6 7 8 9 10
3rd removed: 1 2 4 5 6 7 8 9 10
#include <iostream>
#include <algorithm>
#include <functional>
#include <locale>
#include <string>
using namespace std;
using namespace std::placeholders;
char myToupper (char c)
{
std::locale loc;
return std::use_facet<std::ctype<char> >(loc).toupper(c);
}
int main()
{
string s("Internationalization");
string sub("Nation");
// search substring case insensitive
string::iterator pos;
pos = search (s.begin(),s.end(), // string to search in
sub.begin(),sub.end(), // substring to search
bind(equal_to<char>(), // compar. criterion
bind(myToupper,_1),
bind(myToupper,_2)));
if (pos != s.end()) {
cout << "\"" << sub << "\" is part of \"" << s << "\""
<< endl;
}
}
#include <iostream>
#include <algorithm>
#include <locale>
#include <string>
using namespace std;
char myToupper (char c)
{
std::locale loc;
return std::use_facet<std::ctype<char> >(loc).toupper(c);
}
int main()
{
string s("Internationalization");
string sub("Nation");
// search substring case insensitive
string::iterator pos;
pos = search (s.begin(),s.end(), // string to search in
sub.begin(),sub.end(), // substring to search
[] (char c1, char c2) { // compar. criterion
return myToupper(c1)==myToupper(c2);
});
if (pos != s.end()) {
cout << "\"" << sub << "\" is part of \"" << s << "\""
<< endl;
}
}
calling member functions
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
using namespace std;
using namespace std::placeholders;
class Person {
private:
string name;
public:
Person (const string& n) : name(n) {
}
void print () const {
cout << name << endl;
}
void print2 (const string& prefix) const {
cout << prefix << name << endl;
}
//...
};
int main()
{
vector<Person> coll
= { Person("Tick"), Person("Trick"), Person("Track") };
// call member function print() for each person
for_each (coll.begin(), coll.end(),
bind(&Person::print,_1));
cout << endl;
// call member function print2() with additional argument for each person
for_each (coll.begin(), coll.end(),
bind(&Person::print2,_1,"Person: "));
cout << endl;
// call print2() for temporary Person
bind(&Person::print2,_1,"This is: ")(Person("nico"));
}
#include <functional>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
using namespace std;
using namespace std::placeholders;
class Person {
private:
string name;
public:
Person(const string& n) : name(n) {
}
void print() const {
cout << name << endl;
}
void print2(const string& prefix) const {
cout << prefix << name << endl;
}
//...
};
int main()
{
vector<Person> coll
= { Person("Tick"), Person("Trick"), Person("Track") };
// call member function print() for each person
for_each(coll.begin(), coll.end(),
[](const Person& p) {
p.print();
});
cout << endl;
// call member function print2() with additional argument for each person
for_each(coll.begin(), coll.end(),
[](const Person& p) {
p.print2("Person: ");
});
}
Using lambdas as hash function and equivalence criterion
//print.hpp
#include <iostream>
#include <string>
// PRINT_ELEMENTS()
// - prints optional string optstr followed by
// - all elements of the collection coll
// - in one line, separated by spaces
template <typename T>
inline void PRINT_ELEMENTS(const T& coll,
const std::string& optstr = "")
{
std::cout << optstr;
for (const auto& elem : coll) {
std::cout << elem << ' ';
}
std::cout << std::endl;
}
//hashval.hpp
#pragma once
#include <functional>
// from boost (functional/hash):
// see http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
template <typename T>
inline void hash_combine(std::size_t& seed, const T& val)
{
seed ^= std::hash<T>()(val) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
}
// auxiliary generic functions to create a hash value using a seed
template <typename T>
inline void hash_val(std::size_t& seed, const T& val)
{
hash_combine(seed, val);
}
template <typename T, typename... Types>
inline void hash_val(std::size_t& seed,
const T& val, const Types&... args)
{
hash_combine(seed, val);
hash_val(seed, args...);
}
// auxiliary generic function to create a hash value out of a heterogeneous list of arguments
template <typename... Types>
inline std::size_t hash_val(const Types&... args)
{
std::size_t seed = 0;
hash_val(seed, args...);
return seed;
}
//main.cpp
#include <string>
#include <iostream>
#include <unordered_set>
#include "hashval.hpp"
#include <functional>
#include "print.hpp"
using namespace std;
class Customer {
private:
string fname;
string lname;
long no;
public:
Customer(const string& fn, const string& ln, long n)
: fname(fn), lname(ln), no(n) {
}
string firstname() const {
return fname;
};
string lastname() const {
return lname;
};
long number() const {
return no;
};
friend ostream& operator << (ostream& strm, const Customer& c) {
return strm << "[" << c.fname << "," << c.lname << "," << c.no << "]";
}
};
int main()
{
// lambda for user-defined hash function
auto hash = [](const Customer& c) {
return hash_val(c.firstname(), c.lastname(), c.number());
};
// lambda for user-defined equality criterion
auto eq = [](const Customer& c1, const Customer& c2) {
return c1.number() == c2.number();
};
// create unordered set with user-defined behavior
unordered_set<Customer, decltype(hash), decltype(eq)> custset(10, hash, eq);
// ERROR: unordered_set<Customer,function<size_t(Customer,Customer)>,decltype(eq)> custset(10,hash,eq);
custset.insert(Customer("nico", "josuttis", 42));
PRINT_ELEMENTS(custset);
}