C++primer--lambda式-パラメータバインドbind
,C++11 , , , bind1st bind2nd , bind, , , , 。 。
, (deprecated). 。 bind bind。
#include<iostream>
#include <vector>
#include <algorithm>
#include<numeric>
#include<fstream>
#include<functional>
#include<string>
#include<ostream>
using namespace std;
using namespace std::placeholders;
inline void output_date(const vector<string>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
bool check_size(const string &s, string::size_type sz)
{
return s.size() > sz;
}
void biggies(vector<string> &words, vector<string>::size_type sz)
{
output_date(words);
auto bc = count_if(words.begin(), words.end(), bind(check_size, _1, sz));
}
int main(int argc, char **argv)
{
ifstream in(argv[1]);
if (!in)
{
cerr << "can't open the file";
exit(1);
}
vector<string>words;
string word;
while (in >> word)
words.push_back(word);
biggies(words, 6);
}
lambdaの代わりに関数を使用する方法
この表現関数がlambdaに代わる方法は,実は両者の違いである.lambdaがローカル変数をキャプチャしない場合、それを関数に置き換えるのは簡単ですが、lambdaがローカル変数をキャプチャする場合は簡単ではありません.この場合、アルゴリズムは呼び出し可能なオブジェクトが受け入れるパラメータの個数が関数に必要なパラメータの個数より少ないことを要求します.lambdaはキャプチャしたローカル変数によってこの差を補いますが、一般的な関数ではできません.標準ライブラリはbind関数を提供しています.
bind()がいくつかのパラメータを受け入れる場合?
bindは可変パラメータであるため、最初のパラメータは呼び出し可能な関数オブジェクト、すなわち実際の動作関数Aであり、アルゴリズムで使用される新しい呼び出し可能オブジェクトBを返す.AがX個のパラメータを受け入れる場合、bindのパラメータ個数はX+1であるべきであり、A以外のパラメータはAが受け入れるパラメータに一つ一つ対応しなければならない.これらのパラメータの一部はB(_n)にあり、他のいくつかは関数の局所変数に由来する.
Lambda式の主なコードについては、次のとおりです.
#include<iostream>
#include<vector>
#include<algorithm>
#include<numeric>
#include<string>
#include<fstream>
#include <functional>
using namespace std;
using namespace std::placeholders;
void output_date(const vector<string>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
void output_date(const vector<int>&s)
{
for (auto i = s.begin(); i != s.end(); i++)
{
cout << *i << " ";
}
cout << endl;
}
void output_date(const vector<string>::iterator beg,const vector<string>::iterator iter)
{
for (auto i = beg; i != iter; i++)
{
cout << *i << " ";
}
cout << endl;
}
bool isShorter(const string &s1, const string &s2)
{
return s1.size() < s2.size();
}
bool isEnoughLEngth(const string &s1)
{
return s1.size() > 5;
}
/////////////////////////////lambda ///////////////
void add(int az)
{
auto sumint = [az](int b) { return az + b; };
cout << sumint(1)<<" ";
}
void biggies(vector<string>&words, vector<string>::size_type sz)
{
stable_sort(words.begin(),words.end(),
[sz](const string &s1, const string &s2) { return s1.size() < s2.size(); });
for_each(words.begin(), words.end(), [](const string &s) { cout << s << endl; });
}
void bigge(vector<string> &words, vector<string>::size_type sz,ostream &os=cout,char c=' ')
{
//os 。c ,
for_each(words.begin(), words.end(),
[&, c](const string &s) { os << s << c; });
for_each(words.begin(), words.end(),
[=, &os](const string &s) { os << s << c; });
}
ostream &print(ostream&os, const string &s, char c)
{
return os << s << c;
}
int main(int argc, char**argv)
{
vector<string >vec{ "china", "chinese", "word", "hello", "dear", "marry", "hurt" };
stable_sort(vec.begin(), vec.end(), isShorter);// , , 。
output_date(vec);
auto iter = partition(vec.begin(), vec.end(), isEnoughLEngth);
output_date(vec.begin(), iter);
auto countnum = count_if(vec.begin(), vec.end(),
[](const string &s) { return s.size() > 5; });
cout <<"vec "<< countnum <<" 5 "<< endl;
stable_sort(vec.begin(), vec.end(),
[](const string &s1, const string&s2)
{return s1.size() > 5;});// lanbda ,
auto sum = [](int a, int b) { return a + b; };
cout << sum(6, 5) << endl;;
add(6);
// lambda ,
vector<int>veint{ 1, -2, 3, 67, 32, -6, -32, -32, 6, -3, -523, -45, -5334, -3531, 632, 45, 32, 634, 6, 23, 523 };
transform(veint.begin(), veint.end(), veint.begin(),
[](int i)->int { if (i < 0) return -i; else return i; });
// 、 ,
output_date(veint);
//auto wc = find_if(vec.begin(),vec.end(),bind(_1,add));
system("pause");
}
Lambda式では,関数参照においてかなり便利であり,これはC++11の新しい特性である.