【问题标题】:C++ STL: Using derived virtual class as "Strict Weak Ordering" for std::sort()C++ STL:使用派生虚拟类作为 std::sort() 的“严格弱排序”
【发布时间】:2011-05-03 20:30:10
【问题描述】:

我使用 std::sort() 碰壁了。我有一个纯虚拟类(名为Compare),方法的调用者从它派生(名为MyComp)。我将纯虚拟类用于我的 API 原型:

void Object::DoSort(Compare &comp) {
    std::sort(this->mKeys.begin(),this->mKeys.end(), comp);
}

调用者:

class MyComp: public Compare {
    bool operator()(const Row *r1, const Row *r2)  { ... }
} cmp;
...
obj->DoSort(cmp);

Linux 上的 g++ 编译器抱怨:“无法分配 'Compare' 类型的对象,因为 'Compare' 类型具有抽象虚函数”

即使我将Compare 修改为简单的虚拟(非纯),std::sort() 仍然调用Compare::operator() 代码而不是MyComp::operator()

调用 cmp(r1,r2) 可以正常编译并返回正确的结果。

我必须做错事,否则我不明白。请帮忙!

【问题讨论】:

    标签: c++ sorting stl


    【解决方案1】:

    std::sort(和其他 STL 函数)按值获取比较器对象,因此您的对象被复制,但派生部分(包括其 vtbl)被“切掉”。 p>

    您可以将对象包装在代理中:

    class Proxy
    {
    private:
        Compare &cmp;
    public:
        Proxy(Compare &cmp) : cmp(cmp) {}
        bool operator()(const Row *r1, const Row *r2) { return cmp(r1, r2); }
    };
    
    
    ...
    
    MyCompare cmp = MyCompare();
    
    std::sort(x.begin(), x.end(), Proxy(cmp));
    

    【讨论】:

    • 1) 像魅力一样工作。 2) STL == 邪恶。
    • @0x6adb:邪恶取决于!如果你有它的参考,你不能做例如std::sort(x.begin, x.end(), MyComparator()),例如(您不能将非常量引用绑定到临时对象)。
    • 为什么他们不能用一个将比较器作为参考的版本重载 std::sort 呢? (我必须自己写)。
    • @Super:首先,这会引起歧义;在许多情况下,编译器不知道该调用哪个。
    猜你喜欢
    • 2015-09-20
    • 2013-05-25
    • 2018-08-04
    • 2010-11-20
    • 2013-02-14
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 2014-12-29
    相关资源
    最近更新 更多