簡體   English   中英

是否可以將std :: sort與帶有額外參數的sort函數一起使用?

[英]Is it possible to use std::sort with a sort function that takes extra arguments?

這是我一直在考慮的事情。 我已經做了一些研究而且找不到任何東西,但我也沒有發現任何相反的東西。

考慮<algorithm>std::sort函數。 它需要兩個迭代器和一個函數指針作為參數。 所以,如果我想按字母順序對字符串向量進行排序,我會這樣做:

bool ascending(std::string lhs, std::string rhs) { return lhs < rhs; }

std::sort(my_vector.begin(), my_vector.end(), ascending);

問題是這種類型的sort函數區分大小寫,因此在以大寫“Z”開頭的字符串后面會放置以小寫“a”開頭的字符串。 我看到的唯一可見解決方案是沿着bool ascending_case_insensitive()創建一個額外的函數。 但是,如果我可以使用函數bool ascending()並在sort中使用另外的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));

所以認為這幾乎總結了我的選擇?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM