std :: array是否与旧的C数组兼容? [英] Is the std::array bit compatible with the old C array?

查看:158
本文介绍了std :: array是否与旧的C数组兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std :: array< T,N>的底层位表示 v T u [N] 相同?



是否可以安全地将 N * sizeof(T)字节从一个复制到另一个? (通过 reinterpret_cast memcpy 。)



strong>编辑: 和 reinterpret_cast

code>。



例如,假设我有一些简单的可复制类型 T ,对于某些 N

  struct VecNew {
std :: array< T,N> v;
};

struct VecOld {
T v [N];
};

还有遗留功能

  T foo(const VecOld& x); 

如果表示形式相同,那么此调用是安全的并避免复制:

  VecNew x; 
foo(reinterpret_cast< const VecOld&>(x));


解决方案

我说是)。



根据[array] / 2:


一个聚合([ dcl.init.aggr ]),它可以是
列表初始化的最多N个元素的类型可以转换为
T。


and [dcl.init.aggr]:


一个集合是一个数组或类类]的




  • 没有用户提供,显式或继承的构造函数>


  • 没有私人或受保护的非静态资料成员(条款
    [class.access]),


  • < <>没有虚拟函数([class.virtual])和


  • )。





然后,数据(

指定为:


constexpr T * data()noexcept; code>



返回 [data(),data()+ size )是有效范围, data()== addressof(front())




标准基本上想说它返回一个数组,但为其他实现打开了门。



可能的其他实现是具有单个元素的结构,在这种情况下,您可能会遇到别名问题。但在我看来,这种方法不增加任何东西,只是复杂性。将数组展开到结构体中没有任何效果。



因此,它使没有意义 std :: array 作为数组。



但是存在漏洞。


Is the underlying bit representation for an std::array<T,N> v and a T u[N] the same?

In other words, is it safe to copy N*sizeof(T) bytes from one to the other? (Either through reinterpret_cast or memcpy.)

Edit:

For clarification, the emphasis is on same bit representation and reinterpret_cast.

For example, let's suppose I have these two classes over some trivially copyable type T, for some N:

struct VecNew {
    std::array<T,N> v;
};

struct VecOld {
    T v[N];
};

And there is the legacy function

T foo(const VecOld& x);

If the representations are the same, then this call is safe and avoids copying:

VecNew x;
foo(reinterpret_cast<const VecOld&>(x));

解决方案

I say yes (but the standard does not guarantee it).

According to [array]/2:

An array is an aggregate ([dcl.init.aggr]) that can be list-initialized with up to N elements whose types are convertible to T.

And [dcl.init.aggr]:

An aggregate is an array or a class (Clause [class]) with

  • no user-provided, explicit, or inherited constructors ([class.ctor]),

  • no private or protected non-static data members (Clause [class.access]),

  • no virtual functions ([class.virtual]), and

  • no virtual, private, or protected base classes ([class.mi]).

In light of this, "can be list-initialized" is only possible if there are no other members in the beginning of the class and no vtable.

Then, data() is specified as:

constexpr T* data() noexcept;

Returns: A pointer such that [data(), data() + size()) is a valid range, and data() == addressof(front()).

The standard basically wants to say "it returns an array" but leaves the door open for other implementations.

The only possible other implementation is a structure with individual elements, in which case you can run into aliasing problems. But in my view this approach does not add anything but complexity. There is nothing to gain by unrolling an array into a struct.

So it makes no sense not to implement std::array as an array.

But a loophole does exist.

这篇关于std :: array是否与旧的C数组兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆