在结构数组上使用 c++ std::copy

Posted

技术标签:

【中文标题】在结构数组上使用 c++ std::copy【英文标题】:Using c++ std::copy on an array of structure 【发布时间】:2019-08-08 10:25:25 【问题描述】:

我想使用 std::copy 将现有的结构数组复制到新的结构数组。 '''local_copy()''' 可以使用常规选项。我想知道在下面描述的这种情况下使用 std::copy 的过程-

我尝试了代码并在编译时出现以下错误

#include <iostream>

class BigClass
public:
struct Astruct
    double x[2], v[2];
    int rank;
one_struct;

;

void allocate(struct BigClass::Astruct& one_struct, int i)

one_struct.x[0] = 1.1;
one_struct.x[1] = 1.2;
one_struct.v[0] = 2.1;
one_struct.v[1] = 2.2;
one_struct.rank = i;


void local_copy(struct BigClass::Astruct& dest, struct BigClass::Astruct& source)

dest.x[0] = source.x[0];
dest.x[1] = source.x[1];
dest.v[0] = source.v[0];
dest.v[1] = source.v[1];
dest.rank = source.rank;


void print(struct BigClass::Astruct one_struct)

std::cout << one_struct.rank << " " << one_struct.x[0] << " " << one_struct.x[1] << " " << one_struct.v[0] << " " << one_struct.v[1] << "\n";




int main(int argc, char *argv[]) 

int size = 10;
struct BigClass::Astruct BCobj[size];
for(int i = 0; i < size; i++) allocate(BCobj[i], i);
for(int i = 0; i < size; i++) print(BCobj[i]);

struct BigClass::Astruct second_BCobj[size];
//for(int i = 0; i < size; i++) local_copy(second_BCobj[i], BCobj[i]); // this works
for(int i = 0; i < size; i++) std::copy(BCobj[i+1], BCobj[i], second_BCobj[i]); // not working

for(int i = 0; i < size; i++) print(BCobj[i]);


编译时错误如下-

/usr/include/c++/7/bits/stl_algobase.h:377:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
   typedef typename iterator_traits<_II>::value_type _ValueTypeI;
                                                     ^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:378:57: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
   typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
                                                     ^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:379:64: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<BigClass::Astruct>’
   typedef typename iterator_traits<_II>::iterator_category _Category;
                                                            ^~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:383:9: error: no type named ‘value_type’ in ‘struct std::iterator_traits<BigClass::Astruct>’
   const bool __simple = (__is_trivial(_ValueTypeI)
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~
                   && __is_pointer<_II>::__value
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                   && __is_pointer<_OI>::__value
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     && __are_same<_ValueTypeI, _ValueTypeO>::__value);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:386:44: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<BigClass::Astruct>’
   return std::__copy_move<_IsMove, __simple,
          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                    _Category>::__copy_m(__first, __last, __result);
                        ~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~

提供了一些向量和 int 数据类型的示例。任何人都可以为这种代码结构详细说明 std::copy 的适当顺序吗? 谢谢。

【问题讨论】:

您可以改用std::vector 来避免此问题。 copy 采用两个迭代器,而不是两个元素。使用BCobj + i + 1, BCobj + i 而不是BCobj[i+1], BCobj[i] int size = 10;struct BigClass::Astruct BCobj[size]; -- 这不是有效的 C++ 代码。 C++ 中的数组的大小由常量表达式表示,而不是变量。请改用std::vector——这就是它的设计目的,动态数组的用途。 【参考方案1】:

std::copy 被使用而不是 for 循环,而不是一个。

std::copy(BCobj, BCobj + size, second_BCobj);

本质上是一样的

for(int i = 0; i < size; ++i) 
    second_BCobj[i] = BCobj[i];

另外,不要忘记#include &lt;algorithm&gt;std::copy


std::copy 的参数说明:

std::copy 将 2 个匹配 InputIterator 要求类型的参数和一个 OutputIteretor 类型的参数作为参数。幸运的是,指针符合这些要求,因此我们可以直接使用它们。由于数组名被解释为指向其第一个元素的指针,我们可以将其作为参数直接传递给std::sort


Chef Gladiator建议的更好版本:

std::copy(std::begin(BCobj), std::end(BCobj), std::begin(second_BCobj))

【讨论】:

copy( begin(BCobj), end(BCobj), begin(second_BCobj)) 在查找beginend时考虑ADL会更好。 (或者在C++20中使用ranges::beginranges::end【参考方案2】:

欢迎来到 Stack Overflow。您已经提交了完整的代码。下次还请描述您正在构建的开发环境。更好的是,尝试提供与操作系统和编译器无关的标准 C++ 代码。

这是 C++ 论坛,所以我们喜欢在这里使用标准 C++。您的代码使用std::array 重写如下。这很简单。请学习并享受standard C++。

  #include <array>
  #include <iostream>
  #include <algorithm>

  namespace stack_overflow 

      using namespace std;

      struct BigClass final 
          struct Astruct final 
              double x[2], v[2];
              int rank;
          one_struct;

          friend ostream& operator << (ostream& os, Astruct const & one_struct)
          
              return os << one_struct.rank << " " << one_struct.x[0] << " "
                  << one_struct.x[1] << " " << one_struct.v[0] << " "
                  << one_struct.v[1] ;
          
      ;

      constexpr int size = 10;
      using bcobj_arr = std::array<BigClass::Astruct, size>;

      void populate( bcobj_arr& bcobjects_)
      
          int j 0 ;
          for (auto& one_struct : bcobjects_) 
              one_struct.x[0] = 1.1;
              one_struct.x[1] = 1.2;
              one_struct.v[0] = 2.1;
              one_struct.v[1] = 2.2;
              one_struct.rank = j++;
          
      

      void print(const char prompt[BUFSIZ], bcobj_arr const & bcobjects_ )
      
          cout << "\n\n" << prompt << "\n\n" ;
          for (auto& one_struct : bcobjects_) 
              cout << one_struct << "\n";
          
      

      bool test (int argc, const char* argv[]) 
      
          bcobj_arr BCobj;
          populate(BCobj);
          print("BCobj", BCobj);
            // std::array instances can be copied
            bcobj_arr second_BCobj = BCobj ;
          print("second_BCobj", second_BCobj);
          return true;
      
  

 int main(const int argc, const char * argv[])
 
  stack_overflow::test(argc, argv);
  return 42;
 

代码根本没有注释。我假设您有很多问题,请在下面的 cmets 中提问。我将尝试通过将您指向在线相关文档来回答所有问题。

【讨论】:

以上是关于在结构数组上使用 c++ std::copy的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中使用 HDF5 存储多个 2D 字符数组?

C++、std::copy 和模板

使用 std::copy 复制数组时出现分段错误

如何将 unique_ptr 与 std::copy 一起使用?

C++中vector <int> array;如何像下面数组一样赋值

为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?