std::array中的内存是连续的吗?

19

std::array 的内存是连续的吗?下面的代码是否有效/良好实践?

std::array<type1,Num> arr = //initialize value
type1 * ptr = &arr[0];

那我可以将ptr传递给期望C风格数组的函数吗?


是的,我做了。谢谢你发现了那个。 - Riley
2个回答

33

是的,它是连续的,因为它基本上(实际上)是一个type arr[10];,但具有STL类似的接口。它也不会在最轻微的刺激下衰减为指针。

您可以安全地将&arr[0]传递给期望C风格数组的函数,这是它的设计目标。但是要与STL算法一起使用,只需使用beginend函数:

// either members
std::sort(arr.begin(), arr.end());
// or free from <iterator>
std::sort(std::begin(arr), std::end(arr));

对于语言律师部分,§23.3.2.1 [array.overview] p1:
<array>头文件定义了一个类模板,用于存储固定大小的对象序列。数组支持随机访问迭代器。 array<T,N>的实例存储类型为TN个元素,因此size() == N是不变的。 数组的元素是连续存储的,这意味着如果aarray<T,N>,则它遵循&a[n] == &a[0] + n的标识,其中0 <= n < N。”
并且 §23.3.2.1 [array.overview] p2 中提到:
“数组是一个聚合体(8.5.1),可以使用以下语法进行初始化” array<T,N> a = {initializer-list}; 另外,在p3中,列出了std::array的成员:
T elems[N]; // 仅供说明
[注意: 成员变量elems仅用于说明,以强调array是一个类聚合体。名称elems不是array的一部分。 —结束说明]”

@Als:首先,我无论如何都会收到对我的答案的评论通知,其次,是的。 :) - Xeo
1
@Darren std::array 要求是一个聚合体。 - Luc Danton
@Xeo,Luc:很好,看起来他们已经覆盖了所有基础... :) - Darren Engwirda
为什么优先使用arr.begin()arr.end()而不是begin(arr)end(arr)?我发现有点有趣的是,C++0x终于为自动数组添加了一个容器风格的接口,同时引入了代表范围的单个对象的概念,因此我们不再需要将数组具有容器风格的接口;-) - Steve Jessop
@Steve:我这么做,是因为我能。 ;) - Xeo
显示剩余2条评论

-1

是的,std::array 的内存是连续的。在 VC10 上,它被声明为:

template<class _Ty,
    size_t _Size>
    class array
    { // fixed size array of values
                ... 
         _Ty _Elems[_Size == 0 ? 1 : _Size];
    };

_Elemes 只是一个给定类型的简单数组。


4
这只是一个 std::array 的实现。你的答案是正确的,但你的理由是无效的。其他实现可以用不同的方式编写类。他们不能这样做的原因是会违反规范。你忘记提到了这一点。 - Cody Gray
可能吧,购买GNU实现也采用相同的方法:http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01741.html - Ajay

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