是否有可能使用std :: sort与带额外参数的排序函数?
这是我一直在考虑的事情。我已经做了一些研究,找不到任何东西,但我还没有发现任何相反的事情。是否有可能使用std :: sort与带额外参数的排序函数?
请考虑<algorithm>
中的std::sort
函数。它需要两个迭代器和一个函数指针作为参数。所以,如果我想按字母顺序排序字符串矢量,我会做这样的事情:
bool ascending(std::string lhs, std::string rhs) { return lhs < rhs; }
std::sort(my_vector.begin(), my_vector.end(), ascending);
的事情是,这种类型的排序功能是区分大小写的,所以才会将一个字符串以小写开头“一'以大写字母'Z'开始的字符串之后。我看到的唯一可见的解决方案是沿着bool ascending_case_insensitive()
的线创建附加功能。不过,如果我可以在排序中使用bool ascending()
函数并附加bool is_case_sensitive
参数,那将会很不错。这可能吗?
如果你现在有
bool ascending(std::string lhs, std::string rhs);
std::sort(my_vector.begin(), my_vector.end(), ascending);
你可以有
bool ascending(std::string lhs, std::string rhs, bool case_sensitive);
using namespace std::placeholders;
std::sort(my_vector.begin(), my_vector.end(), std::bind(ascending, _1, _2, false));
的std::bind
点是返回调用时,一个对象,调用绑定的功能,可选改变了论据。您可以使用它来更改参数顺序,添加可选参数或将参数设置为特定的固定值。
由于std::sort需要比较函子的一个实例,因此您可以使用参数给函数的构造函数确定其行为。例如,
class StringCompare
{
public:
StringCompare(bool is_case_sensitive=true) : is_case_sensitive(is_case_sensitive){}
bool operator()(const string&, const string&);///This would handle the comparison using the is_case_sensitive flag
private:
bool is_case_sensitive;
};
std::sort(my_vector.begin(), my_vector.end(), StringCompare(true));//case-sensitive comparison
std::sort(my_vector.begin(), my_vector.end(), StringCompare(false));//case-insensitive comparison
Upvoting提供一种与C++ 03一起使用的方法。可悲的是,并非我们所有人都在使用C++ 11或更高版本,并有权访问std :: bind()。 – GuyGizmo 2016-05-03 22:16:59
有如下,包括函数调用与绑定额外的参数,并通过价值捕获额外的参数lambda表达式的例子:
#include <iostream>// for std::cout
#include <vector>// for std::vector
#include <functional> // for std::bind
#include <algorithm> // for std::sort
bool ltMod(int i, int j, int iMod) {
return (i % iMod) < (j % iMod);
}
int main() {
std::vector<int> v = {3,2,5,1,4};
int iMod = 4;
std::cout << "\nExample for the usage of std::bind: ";
// _1 and _2 stand for the two arguments of the relation iMod is the bound parameter
std::sort(v.begin(),v.end(),std::bind(ltMod,std::placeholders::_1,std::placeholders::_2,iMod));
for(auto i : v) std::cout << i << ',';
iMod = 3;
std::cout << "\nExample for lambda: ";
// lambdas are unnamed inplace functions
// iMod is captured by value. You can use the value within the function.
std::sort(v.begin(),v.end(),[iMod](int i, int j){ return ltMod(i,j,iMod); });
for(auto i : v) std::cout << i << ',';
return 0;
}
/**
Local Variables:
compile-command: "g++ -std=c++11 test.cc -o a.exe"
End:
*/
以为我会回答我的问题,以总结我得到的回应。所以从我所收集的内容来看,我基本上有两种选择。
第一个将写一个lambda函数来处理我的一次性案例。
// Lambda solution.
std::sort(my_vector.begin(), my_vector.end(),
[](std::string const &lhs, std::string const &rhs) // Thanks for optimizing my example code guys. No, seriously. ;)
{
return boost::toupper(lhs) < boost::toupper(rhs);
});
第二个更可重用的选项是创建一个仿函数来处理这些排序情况。
// Functor solution.
class SortAscending
{
private:
bool _is_case_sensitive;
public:
SortAscending(bool is_case_sensitive) :
_is_case_sensitive(is_case_sensitive);
bool operator()(std::string const &lhs, std::string const &rhs)
{
if (_is_case_sensitive)
return boost::toupper(lhs) < boost::toupper(rhs);
else
return lhs < rhs;
}
};
std::sort(my_vector.begin(), my_vector.end(), SortAscending(false));
那么认为这几乎总结了我的选择?
这需要绑定函子/ lambda – deviantfan 2014-10-18 20:27:39
C++ 11或C++ 03? – 2014-10-18 20:27:40
11非常好。 – 2014-10-18 20:28:09