C++嵌套迭代器问题:如何遍历结构体向量?

3

我是C ++的初学者,请原谅我的新手问题。

我试图遍历一个结构体deque。在每个这样的结构体中,都有一个本身是另一种结构体的向量结构体成员。我试图找到这些嵌套结构体的唯一值,并且如果我发现嵌套结构体项目不唯一,则要从deque删除父结构体。我将每个父结构体称为“拆分”。

这是我的结构:

// struct for each action inside each "split".
struct act_struct {
    short int csv_card_index;
    short int act_type;
    short int act_mod1;
    short int act_mod2;
};

// struct for each individual split, the parent struct
struct split_struct {    
    std::vector<short int> cards_in_hand;
    std::vector<short int> cards_drawn;
    std::vector<short int> cards_in_deck;
    std::vector<short int> cards_bf;
    std::vector<short int> cards_mana_disabled;
    std::vector<act_struct> actions;  <--- this is where the act_struct gets nested
    bool played_a_land;
};

// deque holding different split_structs in sequence
typedef std::deque<split_struct> all_splits_que;

就像我之前说过的,我希望遍历deque all_splits_que,它包含了一堆split_struct。然后我想访问每个split_struct的"actions"成员。我想查看所有split_struct项中"actions"成员的序列是否是唯一的,如果不是,则将该split_struct从其deque中删除。

以下是我的初步代码尝试:

// this is a vector where I'll track action vectors i've already encountered, so I can tell
// if the current action vector is unique. if the current action vector is unique, it will get push
// onto this
std::vector<std::vector<act_struct>> used_action_sequences;

// all_splits is an all_splits_que with several split_struct in sequence

// first i create an iterator to loop through all_splits
auto it = all_splits.begin();

while ( it != all_splits.end() ) {
    
    // access the actions struct for this split_struct
    std::vector<act_struct> this_split_acts = it->actions;
    
    // create a new iterator that checks if this_split_acts is already found in 
    // used_action_sequences (ERROR THROWN ON THIS LINE)
    std::vector<std::vector<act_struct>>::iterator it2 = std::find(used_action_sequences.begin(), used_action_sequences.end(), this_split_acts);

}

就我来说,这是我所能做到的了,因为它似乎不喜欢我创建第二个迭代器。我在Geany中使用gcc,这是记录的第一组错误。我不知道它们是什么意思。我做错了什么?我尝试将迭代器it2的类型替换为"auto",但是得到了相同的错误。谢谢。

In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/char_traits.h:39,
                 from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/ios:40,
                 from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/ostream:38,
                 from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/iostream:39,
                 from main.cpp:3:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algobase.h: In instantiation of 'static bool std::__equal<_BoolType>::equal(_II1, _II1, _II2) [with _II1 = const act_struct*; _II2 = const act_struct*; bool _BoolType = false]':
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algobase.h:851:43:   required from 'bool std::__equal_aux(_II1, _II1, _II2) [with _II1 = const act_struct*; _II2 = const act_struct*]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algobase.h:1069:30:   required from 'bool std::equal(_II1, _II1, _II2) [with _II1 = __gnu_cxx::__normal_iterator<const act_struct*, std::vector<act_struct> >; _II2 = __gnu_cxx::__normal_iterator<const act_struct*, std::vector<act_struct> >]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_vector.h:1890:21:   required from 'bool std::operator==(const std::vector<_Tp, _Alloc>&, const std::vector<_Tp, _Alloc>&) [with _Tp = act_struct; _Alloc = std::allocator<act_struct>]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/predefined_ops.h:241:17:   required from 'bool __gnu_cxx::__ops::_Iter_equals_val<_Value>::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<act_struct>*, std::vector<std::vector<act_struct> > >; _Value = const std::vector<act_struct>]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algo.h:120:14:   required from '_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<std::vector<act_struct>*, std::vector<std::vector<act_struct> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const std::vector<act_struct> >]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algo.h:161:23:   required from '_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator<std::vector<act_struct>*, std::vector<std::vector<act_struct> > >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val<const std::vector<act_struct> >]'
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/9.2.0/include/c++/bits/stl_algo.h:3899:28:   required from '_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator<std::vector<act_struct>*, std::vector<std::vector<act_struct> > >; _Tp = std::vector<act_struct>]'        
main.cpp:296:145:   required from here

all_splits,正如我在注释中解释的那样,是一个包含多个split_structs的all_splits_que。我不是在比较两个结构体,而是在查看一个结构体向量是否存在于一堆结构体向量中。 - Geoff L
1
@GeoffL 请编辑您的问题,给出 all_splits 的定义。为什么要使用 std::vector<act_struct> this_split_acts = it->actions; 而不是 const std::vector<act_struct> & this_split_acts = it->actions;?我的意思是至少使用引用而不是复制向量,并且在您不使用修改它时最好也有 const - bruno
1
可能无法理解如何比较两个 std::vector<act_struct> 对象。 - kesarling He-Him
我认为你是正确的,它不知道如何比较这两个。我尝试用一个更简单的迭代器替换第二个迭代器it2,检查一些简单的int向量是否包含一个int,这样就可以了。那么,我该如何检查一个结构体向量的向量是否包含某个结构体向量呢? - Geoff L
1个回答

1
你需要在act_struct上定义operator==,因为std::find需要它来比较两个std::vector<act_struct>
示例:
#include <vector>
#include <deque>
#include <algorithm>

// struct for each action inside each "split".
struct act_struct {
    short int csv_card_index;
    short int act_type;
    short int act_mod1;
    short int act_mod2;
    friend bool operator==(const act_struct & v1, const act_struct & v2) {
       return v1.csv_card_index == v2.csv_card_index; // <<< ADDED >>>
    }
};

// struct for each individual split, the parent struct
struct split_struct {    
    std::vector<short int> cards_in_hand;
    std::vector<short int> cards_drawn;
    std::vector<short int> cards_in_deck;
    std::vector<short int> cards_bf;
    std::vector<short int> cards_mana_disabled;
    std::vector<act_struct> actions;  //<--- this is where the act_struct gets nested
    bool played_a_land;
};

// deque holding different split_structs in sequence
typedef std::deque<split_struct> all_splits_que;

int main()
{
  
  // this is a vector where I'll track action vectors i've already encountered, so I can tell
  // if the current action vector is unique. if the current action vector is unique, it will get push
  // onto this
  std::vector<std::vector<act_struct>> used_action_sequences;
  
  // all_splits is an all_splits_que with several split_struct in sequence
  all_splits_que all_splits; // <<< ADDED >>>
  
  // first i create an iterator to loop through all_splits
  auto it = all_splits.begin();
  
  while ( it != all_splits.end() ) {
    
    // access the actions struct for this split_struct
    std::vector<act_struct> this_split_acts = it->actions; // better to have const ref
    
    // create a new iterator that checks if this_split_acts is already found in 
    // used_action_sequences 
    std::vector<std::vector<act_struct>>::iterator it2 = std::find(used_action_sequences.begin(), used_action_sequences.end(), this_split_acts);

  }
}

编译:
pi@raspberrypi:/tmp $ g++ -Wall c.cc
c.cc: In function ‘int main()’:
c.cc:49:52: warning: variable ‘it2’ set but not used [-Wunused-but-set-variable]
     std::vector<std::vector<act_struct>>::iterator it2 = std::find(used_action_sequences.begin(), used_action_sequences.end(), this_split_acts);
                                                    ^~~
pi@raspberrypi:/tmp $ 

也许在act_struct上正确的operator==需要比较所有字段,我只是放了一个伪定义来展示代码编译。

正如我在备注中所说,我鼓励您进行替换。

std::vector<act_struct> this_split_acts = it->actions;

const std::vector<act_struct> & this_split_acts = it->actions;

和可能

std::vector<std::vector<act_struct>>::iterator it2
可以
 std::vector<std::vector<act_struct>>::const_iterator it2

1
@bruno,没关系(刚才不得不离开一会儿:P)。最重要的是问题得到了回答,我们能够帮助到别人 :)。 - kesarling He-Him
1
@GeoffL,另外,请看一下bruno编译代码的方式。通常打开所有编译器警告以进行有效调试是一个好习惯。 - kesarling He-Him
1
@bruno 再次感谢您的回答。我有一个问题。当比较 act_structs 的 2 个向量时,您所做的更改是否会影响每个向量中出现的 act_structs 的顺序,或者它只是检查向量是否包含相同的 act_structs? - Geoff L
@GeoffL,了解更多信息,请查看,同时,如果您发现它不错,请像我一样UV这个答案 :) - kesarling He-Him
@GeoffL 要使两个向量相等,它们必须包含相同位置的相同元素,因此首先它们需要具有相同数量的元素。这里的“相同”是指 operator== 返回 true。 - bruno
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接