C++ 之使用标准库函数对象和函数适配器

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 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的目的


你可能感兴趣的:(C++)