在结构数组上使用 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 <algorithm>
为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))
在查找begin
和end
时考虑ADL会更好。 (或者在C++20中使用ranges::begin
和ranges::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 字符数组?
如何将 unique_ptr 与 std::copy 一起使用?