C++ Primer 习题14.37
使用标准库函数对象和函数适配器,定义一个对象用于能:
1. 检查大于1024的所有值;
2. 查找不等于pooh 的所有字符串
3. 将所有值乘以2
#include
#include
#include
#include
#include
#include
#include
#include
#include
bool GT6(const std::string &s)
{
return s.size() >6;
}
class GT_cls
{
public:
GT_cls(std::size_t val = 0):bound(val) {}
bool operator() (const std::string & s) { return s.size() >= bound;}
private:
std::string::size_type bound;
};
class equal_cls
{
public:
equal_cls(int i = 0):val(i) {}
bool operator() (const int & i ) { return i==val; }
private:
int val;
};
//test code
int main()
{
std::vector words;
std::string word;
while(std::cin>>word)
{
words.push_back(word);
}
std::vector::size_type wc = std::count_if(words.begin(),words.end(),GT6);
std::cout<::size_type wc1 = std::count_if(words.begin(),words.end(),GT_cls(6));
std::cout<::size_type wc2 = std::count_if(words.begin(),words.end(),GT_cls(2));
std::cout<::iterator i = std::find_if(words.begin(), words.end(),GT_cls(2));
std::cout<<*i< ivec(10);
std::vector::size_type cn = std::count_if(ivec.begin(), ivec.end(),equal_cls());
std::cout<::size_type cn1 = std::count_if(ivec.begin(),ivec.end(),equal_cls(10));
std::cout< ivec;
ivec.reserve(1030);
for(int i = 0 ; i <1030 ;++i)
{
ivec.push_back(i);
}
//find all value that is greater than 1024
std::vector::iterator result = std::find_if(ivec.begin() , ivec.end() , std::bind2nd(std::greater() ,1024) );
while(result != ivec.end())
{
std::cout<<*result<() ,1024) );
}
std::vector svec;
svec.push_back("hello world");
svec.push_back("test");
svec.push_back("huqijun");
svec.push_back("pooh");
//find all value that is not equal to "pooh"
std::vector::iterator ret = std::find_if(svec.begin(),svec.end(),std::bind2nd(std::not_equal_to(),"pooh") );
while(ret != svec.end())
{
std::cout<<*ret<(),"pooh") );
}
//double every value
std::vector ivec2;
ivec2.reserve(12);
for(int i = 0; i<12 ; ++i)
{
ivec2.push_back(i);
}
std::for_each(ivec2.begin(),ivec2.end(),std::bind2nd(std::multiplies(),2) );
for(std::vector::iterator i = ivec2.begin() ; i!= ivec2.end() ; ++i)
{
std::cout<<*i<
return 0;
}
上面的代码,最后一段实现将所有值乘以2 是失败的,没有实现目的
原因是for_each 算法是不改变序列的算法, for_each 会忽略第三个参数函数的返回值:
UnaryFunction for_each( InputIt first, InputIt last, UnaryFunction f );
|
||
Applies the given function object f
to the result of dereferencing every iterator in the range [first, last)
, in order.
If InputIt
is a mutable iterator, f
may modify the elements of the range through the dereferenced iterator. If f
returns a result, the result is ignored.
而std::mutiplies
constexpr T operator()(const T &lhs, const T &rhs) const { return lhs * rhs; }
所以用for_each 和std::mutiplies 是实现不了将所有值乘2的目的
std::transform(b.begin(),b.end(), b.begin(),std::bind2nd(std::multiplies(),2) );
使用std::tranform 可以实现我们目的:
std::transform
applies the given function to a range and stores the result in another range, beginning at d_first
.
std::transform会见f 运算的结果保存下来,所以可以实现都乘以2的目的