C++ STL算法/函数

C++ STL算法/函数,c++,stl,C++,Stl,我正在尝试使用转换算法(或STL的任何其他部分)来更改整数序列。如果当前元素大于5,则保留它。否则使用5 这不会编译: std::vector<int> vec; vec.push_back(6); vec.push_back(2); vec.push_back(9); vec.push_back(4); vec.push_back(7); std::transform(vec.begin(), vec.end(), vec.begin(), std::bind1st(std::m

我正在尝试使用转换算法(或STL的任何其他部分)来更改整数序列。如果当前元素大于5,则保留它。否则使用5

这不会编译:

std::vector<int> vec;
vec.push_back(6);
vec.push_back(2);
vec.push_back(9);
vec.push_back(4);
vec.push_back(7);

std::transform(vec.begin(), vec.end(), vec.begin(), std::bind1st(std::max<int>(), 5));
std::向量向量向量机;
向量推回(6);
向量推回(2);
向量推回(9);
向量推回(4);
向量推回(7);
std::transform(vec.begin(),vec.end(),vec.begin(),std::bind1st(std::max(),5));

我没有访问C++11的权限。

不幸的是,您不能直接将
bind*
与函数指针一起使用。为了解决这个问题,您通常会使用
std::ptr_fun
,但在您的情况下,这一点都不起作用1。因此,前进的方向是将
std::max
包装成一个函子:

template <typename T>
struct max : std::binary_function<T, T, T> {
    T operator ()(T value, T min) const {
        return std::max(value, min);
    }
};
模板
struct max:std::二进制函数{
T运算符()(T值,T最小值)常量{
返回标准::最大值(值,最小值);
}
};
用法:

std::transform(vec.begin(), vec.end(), vec.begin(), std::bind2nd(max<int>(), 5));
std::transform(vec.begin(),vec.end(),vec.begin(),std::bind2nd(max(),5));

1看起来好像
std::bind1st(std::ptr_fun(&std::max)),5
应该可以工作,但不幸的是,此模板实例化创建了两个相同的
操作符()
重载,因为
std::max
将其参数作为
const
可以使用而不是转换。这允许您使用预定义的比较函数,如
std::less
std::greer
,而不是
std::max

std::replace_if(vec.begin(),vec.end(),std::bind2nd(std::less<int>(),5),5);
std::replace_if(vec.begin()、vec.end()、std::bind2nd(std::less()、5)、5);

是一个很好的例子。

为什么现有的两个答案用具有不同名称的相同实现的函数/函子替换了完美的
std::max
<代码>标准::最大值非常好;你使用旧活页夹的方式是错误的

你说你没有C++11。你有提振吗?Boost.Bind将完成以下任务:

std::transform(vec.begin(), vec.end(), vec.begin(),
               boost::bind(&std::max<int>, _1, 5));

对于此任务,更合适的算法是
std::replace\u if
。比如说

#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>


int main() 
{
    std::vector<int> vec;

    vec.push_back( 6 );
    vec.push_back( 2 );
    vec.push_back( 9 );
    vec.push_back( 4 );
    vec.push_back( 7 );

    for ( std::vector<int>::size_type i = 0; i < vec.size(); i++ )
    {
        std::cout << vec[i] << ' ';
    }
    std::cout << std::endl;

    std::replace_if( vec.begin(), vec.end(),
                     std::bind2nd( std::less<int>(), 5 ), 5 );

    for ( std::vector<int>::size_type i = 0; i < vec.size(); i++ )
    {
        std::cout << vec[i] << ' ';
    }
    std::cout << std::endl;

    return 0;
}

max
函数赋给
std::bind1st
时,不应调用该函数。你想给它函数,而不是没有参数调用它的结果。@chris啊,你删除了你的旧(正确)评论真是太遗憾了,我在回答中提到了它。;-)@KonradRudolph,噢,天哪,我以为我疯了,但我忘了它需要类型别名。更现代的工具在没有强制执行的情况下也会这样做,所以我忘了。@chris是的,C++98
bind*
函数完全是一个累赘。嗯,事后诸葛亮是20/20。为什么我们需要二进制函子?@P0W钳制是一种通用算法。它应该是一个通用函数,而不是为此调用编写的定制函数。因此,my
clamp_lower
是一个通用功能,可与
std::bind2nd
一起使用,类似于OP的用法。您的代码是完全可以接受的()替代方案,但即使我们不需要闭包,它也需要使用闭包。“很遗憾,您不能使用函数指针绑定”是错误的,这就是
std::ptr_fun
的含义for@PiotrS. 是的,我完全忘记了这一点(和chris在问题下方的评论中一样……很有趣)。写一个答案,然后我可以删除我的。@KonradRudolph,只需更新你的答案,因为这里仍然不能使用
std::max
,即使有ptr\u fun。
std::ptr\u fun
也帮不上忙。它重载
operator()
,使
std::max
具有两个相同的重载。当移到C++11时,代码也会中断,因为
std::max
有两个重载。根据C++11附录D.8.2.1(我没有C++98标准),
ptr\u fun
(或者它返回的
指向二进制函数的指针
)根本没有重载
操作符()。你的意思是对
ptr\u fun
本身的调用是不明确的吗?如果是这样的话,那只是因为新的
初始值设定项\u列表
重载,这也是仅限C++11的。我的代码在C++98中应该可以正常工作。我尝试了你的解决方案,它确实给了我一个编译错误。无论如何谢谢:-)@SebastianRedlm对不起,我是说
std::binder1st
operator()
。它重载了
const T&
T&
,所以当
T
const int&
时,它们的结果是一样的。哇,我不知道旧的活页夹那么坏。这真是太好了!这正是我想要的,尽管我仍然好奇为什么@sebastian解决方案不起作用。谢谢你,弗拉德!
#include <iostream>
#include <algorithm>
#include <functional>
#include <vector>


int main() 
{
    std::vector<int> vec;

    vec.push_back( 6 );
    vec.push_back( 2 );
    vec.push_back( 9 );
    vec.push_back( 4 );
    vec.push_back( 7 );

    for ( std::vector<int>::size_type i = 0; i < vec.size(); i++ )
    {
        std::cout << vec[i] << ' ';
    }
    std::cout << std::endl;

    std::replace_if( vec.begin(), vec.end(),
                     std::bind2nd( std::less<int>(), 5 ), 5 );

    for ( std::vector<int>::size_type i = 0; i < vec.size(); i++ )
    {
        std::cout << vec[i] << ' ';
    }
    std::cout << std::endl;

    return 0;
}
6 2 9 4 7 
6 5 9 5 7