C++ STL算法/函数
我正在尝试使用转换算法(或STL的任何其他部分)来更改整数序列。如果当前元素大于5,则保留它。否则使用5 这不会编译: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
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++98bind*
函数完全是一个累赘。嗯,事后诸葛亮是20/20。为什么我们需要二进制函子?@P0W钳制是一种通用算法。它应该是一个通用函数,而不是为此调用编写的定制函数。因此,myclamp_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