2017-04-04 52 views
1

我有以下情況:的std ::目錄::合併()包含列表失敗對象

#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 2015年社區

+1

「merge」是「將兩個排序列表合併成一個新的排序列表」,並且這需要一些手段來明確原因排序元素; 「將所有元素從另一個列表移動到這個元素」的功能是「拼接」。你實際需要什麼? –

回答

3

正如documentationstd::list::merge說:

合併兩個分類列表爲一體。

並進一步:

第一個版本使用運營商<的元素

比較那麼您可能需要爲您提供結構或operator<使用重載的版本使用自定義比較。例如獨立的功能可能是:

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

一種可能的方法出了問題是定義一個有意義的關係operator<定義您class Example對象的順序。這可以通過以下方式完成:

  1. 包含該類的過載operator<將隱式使用。
  2. merge()函數中直接插入作爲第二個參數的Lambda表達式。
  3. 獨立的比較類,它的對象實例化的merge()

例如可以作爲第二個參數,你可以這樣做:

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

給予的std ::目錄::合併的方式比較

class Examples{...}; 

例如,你可以通過在拉姆達做到這一點

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 ::目錄::合併就已經知道如何比較這些(假設你想要的std ::對默認的比較規則)