std::sort 使用继承的仿函数

Posted

技术标签:

【中文标题】std::sort 使用继承的仿函数【英文标题】:std::sort using inherited functor 【发布时间】:2013-03-25 00:22:34 【问题描述】:

我想使用不同的策略对向量进行排序。但我不知道如何传递一个子函子并稍后在std::sort 中使用它。每当我使用抽象类进行排序策略时,我都会遇到cannot allocate an object of abstract type 错误。有没有办法将继承的函子用作std::sort 参数?谢谢!

#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;

【问题讨论】:

不相关,但比较器的函数运算符应该是const。 IE。 virtual bool operator()(const int&amp; a, const int&amp; b) const = 0; 【参考方案1】:

您必须使用std::ref(),否则参数将按值传递(导致尝试复制构造BaseSort 类型的对象,这是非法的,因为BaseSort 是抽象的 - 即使它是不,你会得到切片):

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

【讨论】:

cppreferencestd::ref 仅是 C++11 - 人们在拥有 std::ref 之前是如何处理这个问题的? @us2012:如果我没记错的话,Boost 有一个boost::refboost::cref @us2012 老实说,它根本不会经常出现——您总是可以使用手动包装器来解决它。 @BorisMikhaylov:很高兴我能帮上忙 :)

以上是关于std::sort 使用继承的仿函数的主要内容,如果未能解决你的问题,请参考以下文章

Vector的仿函数用法

为啥我不能将带有互斥锁的仿函数传递给线程?

实现一个可以存储其函数参数的仿函数模板

为啥 C++11 不能将不可复制的仿函数移动到 std::function?

C ++中的仿函数以防止重复?

迭代器与仿函数