【问题标题】:How can I use std::sort with objects that have no copy constructor?如何将 std::sort 与没有复制构造函数的对象一起使用?
【发布时间】:2016-04-05 17:44:11
【问题描述】:

我正在尝试对包含不可复制构造或默认构造(但可移动构造)的对象的向量进行排序,但我收到有关编译器无法为 swap 找到有效函数的错误。我认为拥有一个移动构造函数就足够了。我在这里错过了什么?

class MyType {
public:
    MyType(bool a) {}
    MyType(const MyType& that) = delete;
    MyType(MyType&& that) = default;
};

int main(void) {
    vector<MyType> v;
    v.emplace_back(true);
    sort(v.begin(), v.end(), [](MyType const& l, MyType const& r) {
        return true;
    });
}

【问题讨论】:

    标签: c++ sorting c++11 move-semantics


    【解决方案1】:

    您需要明确定义move assignment operator,因为这也是std::sort 尝试的(不仅仅是移动构造)。请注意,移动赋值运算符is prohibited 的编译器生成由用户提供的复制构造函数以及用户提供的移动构造函数的存在(即使它们是delete-ed)。示例:

    #include <vector>
    #include <algorithm>
    
    class MyType {
    public:
        MyType(bool a) {}
        MyType(const MyType& that) = delete;
        MyType(MyType&& that) = default;
        MyType& operator=(MyType&&) = default; // need this, adapt to your own need
    };
    
    int main(void) {
        std::vector<MyType> v;
        v.emplace_back(true);
        std::sort(v.begin(), v.end(), [](MyType const& l, MyType const& r) {
            return true;
        });
    }
    

    Live on Coliru

    Howard Hinnant(C++11 中移动语义的主要贡献者)的 slides 非常有用,以及来自Effective Modern C++第 17 条:了解特殊成员函数生成斯科特迈耶斯。

    【讨论】:

    • 根据 cppreference,std::sort 要求类型可移动构造可移动分配。
    • 正确。元素不能被移动构造,因为它们都已经存在;它们必须被移动赋值来交换它们的值。
    • @LightnessRacesinOrbit 谢谢,我不确定为什么std::sort 需要 使其元素也可移动。我的猜测是它使用了一个临时的(可能通过std::swap),它是移动构造的。
    • @vsoftco:是的,我想是这样的
    • 或者,更准确地说,规范允许std::sort() 的实现使用临时的。允许使用临时(通过要求移动构造)与要求它不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-24
    • 1970-01-01
    • 2012-01-10
    • 1970-01-01
    • 2012-10-06
    相关资源
    最近更新 更多