簡體   English   中英

無法將std :: set of iterator中的元素插入到std :: list中

[英]Cannot insert element in std::set of iterator to std::list

在顯示給出編譯器錯誤的代碼之前,我想簡要解釋為什么我需要一組迭代器到列表,只是為了避免像“你真的需要嗎?”這樣的評論。 或者可能將它們改為注釋“你的代碼可以用這種方式解決......但是我應該像這樣解決原來的問題”。 你可以跳過閱讀並直接進入最后一節(“不編譯代碼”)。

背后的原因

我構建了一個有向二分加權圖。 每個弧都存儲在一個結構中

typedef struct edge_ {
    int src;
    int des;
    double w; //weight of the arc
}edge;

我使用這樣的結構列表存儲有關圖形的信息。

list<edge> all_edges;

在那之后,我按重量對弧進行排序,然后將它們循環,從最輕到最重。 因為我想從循環中的all_edges刪除一些元素, all_edges在每個循環步驟的開始我調用

list<edge>::iterator smallest = all_edges.begin();

在該循環的每一步中,在完成了弧的權重之后,我想從圖中刪除所有從src離開或以des結尾的節點。 為此,在構建圖形的過程中,我創建了兩個向量,一個用於二分圖的每個組件,由它們的元素索引,並且在每個向量的每個位置,我將所有迭代器的列表存儲到邊緣all_edges ,其離開與所考慮的向量的位置對應的節點。 代碼如下(“小”和“大”是我識別二分圖的兩個組成部分的方式)

vector<list<list<edge>::iterator>> edges_from_small(small.size());
vector<list<list<edge>::iterator>> edges_from_big(big.size());

這是我用來填充上述向量的代碼

//inside a loop...
    edge e;
    e.src = ...
    e.des = ...
    e.w = ...
    all_edges.push_back(e);                
    edges_from_small[e.src].push_back(--(all_edges.end()));
    edges_from_big[e.des].push_back(--(all_edges.end()));

假設我要刪除邊緣e 我想嘗試循環edges_from_small[e.src]所有元素,並為每個元素調用all_edges.erase(iterator) ,但這樣做,因為邊緣可以在edges_from_smalledges_from_big列出,我會結束嘗試使用解除引用的迭代器刪除元素!

設置將是一個解決方案! 我只需要創建一組list<edge>::iterator並用edges_from_small[e.src]edges_from_big[e.des]的元素填充它,然后,因為刪除了重復項,刪除所有元素從列表all_edges

但我的代碼沒有編譯,它給我一個我無法理解的錯誤,在以下某行之一:

set<list<edge>::iterator> to_remove;

for (auto it = edges_from_small[smallest->src].begin(); it != edges_from_small[smallest->src].end(); ++it) {
        to_remove.insert(*it); //error here! 
    }
for (auto it = edges_from_big[smallest->des].begin(); it != edges_from_big[smallest->des].end(); ++it) {
        //to_remove.insert(*it); //error here!
    }
for (auto it = to_remove.begin(); it != to_remove.end(); ++it) {
        all_edges.erase(*it);
    } 

編譯器為我提供了一個非常大的輸出(都參考上面的行),目前我只放了第一行和最后一行,我認為這是最具指示性的。

g++ -ggdb3 -g -O0 -std=c++14 -Wall -Werror -o compare main.cpp peaks.cpp common.cpp compare.cpp parameters.cpp 
In file included from compare.cpp:1:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iostream:38:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/ios:216:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__locale:15:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:439:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:628:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:606:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/iterator:344:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__functional_base:63:21: error: 
      invalid operands to binary expression ('const std::__1::__list_iterator<_edge,
      void *>' and 'const std::__1::__list_iterator<_edge, void *>')
        {return __x < __y;}
                ~~~ ^ ~~~
....................MUCH MORE OUTPUT....................
compare.cpp:226:23: note: in instantiation of member function
      'std::__1::set<std::__1::__list_iterator<_edge, void *>,
      std::__1::less<std::__1::__list_iterator<_edge, void *> >,
      std::__1::allocator<std::__1::__list_iterator<_edge, void *> > >::insert'
      requested here
            to_remove.insert(*it);
                      ^
1 error generated.
make: *** [compare] Error 1

Compilation exited abnormally with code 2 at Tue Sep  5 17:34:39

有關該線路有什么問題的任何想法?

不編譯代碼

typedef struct _edge {
    int src;
    int des;
    double w; //weight of the arch
}edge;

list<edge> all_edges;
vector<list<const list<edge>::iterator>> edges_from_small(small.size());
vector<list<const list<edge>::iterator>> edges_from_big(big.size());

//graph construction    
//for loop ...
    edge e;
    e.src = ...
    e.des = ...
    e.w = ... 
    all_edges.push_back(e);
    edges_from_small[e.src].push_back(--(all_edges.end())); 
    edges_from_big[e.des].push_back(--(all_edges.end()));
//end of loop

list<edge>::iterator smallest = all_edges.begin();
set<list<edge>::iterator> to_remove;
for (auto it = edges_from_small[smallest->src].begin(); 
     it != edges_from_small[smallest->src].end(); ++it) {
    to_remove.insert(*it); //<--- COMPILER ERROR HERE, you can see the error description in the last lines of the previous paragraph
}    

std::list::iterator s無法排序,因為沒有函數或運算符來比較它們(wrt less / greater)。

使用std::unordered_set代替,這不需要對元素進行排序,它使用元素的哈希將它們放入桶中。 您可能必須提供哈希函數,只需在std::unordered_setnamespace std放置std::hash的重載即可查找並使用它。
另請注意, std::unordered_set具有插入的平均常量時間復雜度與std::set的對數時間復雜度

你面臨的問題是std :: set需要元素來實現operator <(a,b) (或者,實際上,你沒有指定比較器使用std :: less的聲明)。 現在, std :: list的迭代器BidirectionalIterator ,缺少所述的opeator。

已經存在的答案對於你的問題的原因是正確的,但是你可能想要考慮boost :: bimap並看看它是否適合你的問題(我很難理解你正在做的算法而沒有看到你寫的整個代碼)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM