对于包含对象的列表,std :: list :: merge()失败

时间:2017-04-04 17:11:47

标签: c++ c++11

我有以下情况:

#include <list>

struct Example
{
    double p1;
    double p2;
};

void f()
{
    std::list<Example> list1;
    std::list<Example> list2;
    list1.merge(list2);
}

在构建过程中,我遇到错误:

C2672 'operator __surrogate_func': no matching overloaded function found

C2893 Failed to specialize function template 'unknown-type std::less<void>::operator() (_Ty1 &&,_Ty2&&) const'

如果我评论最后一行代码,则构建成功。我发现很难相信包含对象的列表无法合并,所以:我错过了什么?

PS。我使用Visual Studio Community 2015

3 个答案:

答案 0 :(得分:3)

documentation std::list::merge中所述:

  

将两个已排序列表合并为一个。

进一步说:

  

第一个版本使用operator&lt;比较元素

因此,您需要为您的结构提供operator<或使用自定义比较器的重载版本。例如,独立功能可以是:

bool operator<( const Example &e1, const Example &e2 ) {
     return std::tie( e1.p1, e1.p2 ) < std::tie( e2.p1, e2.p2 );
}

答案 1 :(得分:1)

解决问题的一种可能方法是定义一个有意义的关系operator<,用于定义class Example个对象的顺序。这可以通过以下方式完成:

  1. 包含该类的重载operator<,将隐式使用。
  2. Lambda表达式直接作为merge()函数中的第二个参数插入。
  3. 单独的比较类,其对象实例化可用作merge()
  4. 中的第二个参数

    例如,您可以执行以下操作:

    bool operator< (const Example& lhs, const Example& rhs) const
    {
        return lhs.p1 < rhs.p1; // if p1 is used as a criterion   
    }
    

答案 2 :(得分:0)

给std :: list :: merge一种比较方式

class Examples{...};
例如,您可以通过传入lambda

来完成此操作
void f()
{
    std::list<Example> list1;
    std::list<Example> list2;
    list1.merge(list2,[](Example e1,Example e2)
    {
        return (e1.p1==e2.p1)? (e1.p2 < e2.p2) : (e1.p1 < e2.p1);
    });
}

或者你可以做到

using Example = std::pair<double,double>;

然后std :: list :: merge已经知道如何比较这些(假设你想要std :: pair的默认比较规则)