2013-03-25 46 views
5

我想使用不同的策略來排序向量。但我不知道如何傳遞一個子函數,並在稍後使用它在std::sort中。每當我使用抽象類進行排序策略時,我最終會遇到cannot allocate an object of abstract type錯誤。有沒有辦法使用繼承函子作爲std::sort參數?謝謝!std ::使用繼承的函子排序

#include <iostream> 
#include <vector> 
#include <algorithm> 
using namespace std; 


class BaseSort{ 
public: 
    virtual ~BaseSort() {}; 
    virtual bool operator()(const int& a, const int& b) = 0; 
}; 

class Asc : public BaseSort{ 
public: 
    bool operator()(const int& a, const int& b){ 
     return a < b; 
    } 
}; 

class Desc : public BaseSort{ 
public: 
    bool operator()(const int& a, const int& b){ 
     return a > b; 
    } 
}; 

void print(const vector<int>& values) { 
    for (unsigned i = 0; i < values.size(); ++i) { 
     cout << values[i] << ' '; 
    } 
    cout << endl; 
} 

int main() { 
    vector<int> values = {2,1,3}; 
    sort(values.begin(), values.end(), Asc()); // {1,2,3} 
    print(values); 
    sort(values.begin(), values.end(), Desc()); // {3,2,1} 
    print(values); 
    Asc* asc = new Asc(); 
    sort(values.begin(), values.end(), *asc); // {1,2,3} 
    print(values); 
    BaseSort* sortStrategy = new Desc(); 
    sort(values.begin(), values.end(), *sortStrategy); //cannot allocate an object of abstract type ‘BaseSort’ 
    print(values); 
    return 0; 
} 
+1

沒有關係的,但是比較器的功能,操作者應'const'。即'虛擬布爾運算符()(const int&a,const int&b)const = 0;' – WhozCraig 2013-03-25 00:27:23

回答

9

你必須使用std::ref(),否則,參數將通過值傳遞(導致試圖複製構建BaseSort類型的對象,這是非法的,因爲BaseSort是抽象的 - 即使不是這樣,你會得到切片):

sort(values.begin(), values.end(), std::ref(*sortStrategy)); 
//         ^^^^^^^^ 
+0

@DrewDormann:感謝您的更正:) – 2013-03-25 00:30:53

+1

'cppreference'說'std :: ref'只是C++ 11 - 人們在使用'std :: ref'之前如何處理這個問題? – us2012 2013-03-25 00:32:57

+1

@ us2012:如果我沒有記錯的話,Boost有一個'boost :: ref'和'boost :: cref' – 2013-03-25 00:33:39