是否可以将std::sort与需要额外参数的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"开头的字符串后面放一个以小写字母"a"开头的字符。我看到的唯一可见的解决方案是按照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

下面的例子包括一个带有绑定额外参数的函数调用和一个按值捕获额外参数的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));

所以你认为这几乎概括了我的选择吗?

最新更新