如何声明指向 C++11 std::array 的指针?

Posted

技术标签:

【中文标题】如何声明指向 C++11 std::array 的指针?【英文标题】:How do you declare a pointer to a C++11 std::array? 【发布时间】:2014-04-09 08:44:45 【问题描述】:

根据变量,我需要选择 SeedPositions32 或 SeedPositions16 数组以供进一步使用。我认为指针会允许这样做,但我无法播种使其工作。我尝试了以下方法。

array<int>* ArrayPointer;
//array<typedef T, size_t Size>* ArrayPointer;
array<int,32> SeedPositions32 = 0,127,95,32,64,96,31,63,16,112,79,48,15,111,80,
                               47,41,72,8,119,23,104,55,87,71,39,24,7,56,88,103,120;
array<int,16> SeedPositions16 = ...

【问题讨论】:

您可以使用 std::array::data 来获取数据指针。返回的指针只会使用 std::array 的第一个模板参数输入。看起来这就是你想要的。 这个问题是the XY problem 的一个案例:您有一个想要使用的解决方案,并寻求建议以使该特定解决方案发挥作用。但是你从来没有告诉我们你实际上试图解决什么问题。可能还有其他(甚至更好)的解决方案。 @JoachimPileborg - 我正在尝试创建一个网球锦标赛模拟器,其中游戏的结果是随机的(有点)。大满贯赛事共有 128 名球员,其中 32 名是种子球员。目前我正试图将种子放在适当的位置。我在升序排列的数组中随机生成了球员的实力。理想情况下,我会有一个算法将每个玩家放在抽签中的正确位置,但我还没有想出一个,所以我手动输入位置作为数组索引,然后打算选择合适的位置. 【参考方案1】:

std::array 有一个尺寸模板参数。两个大小不同的std::array 模板实例是不同的类型。所以你不能有一个指针可以指向不同大小的数组(除非void*诡计,它会打开自己的蠕虫罐。)

您可以为客户端代码使用模板,或者改用std::vector&lt;int&gt;

例如:

template <std::size_t N>
void do_stuff_with_array(std::array<int, N> the_array)

  // do stuff with the_array.


do_stuff_with_array(SeedPositions32);
do_stuff_with_array(SeedPositions16);

请注意,您还可以获得指向数据的指针:

int* ArrayPtr =  SeedPositions32.data();

但是在这里,您丢失了尺寸信息。您必须独立跟踪它。

【讨论】:

是否可以获得指向底层“裸”数组的指针? @Mhd.Tahawi std::array::data 或 std::array[0]. @Mhd.Tahawi 你可以获得一个指向底层数据的指针,但是你会丢失类型信息(特别是大小)。 注意:经常使用的类是ArrayRefarray_view,包含指向数组的指针和数组大小,以及重载所有有用的运算符(呈现容器接口)。不幸的是,它还不是标准的,但很容易编码。它的主要问题是协调其生命周期与底层存储的生命周期...... 很失望std 中没有 ArrayRef/array_view。 Rust 还为不同长度的静态/堆栈分配数组([T; N])提供了不同的类型,但至少它们都强制转换为&amp;[T],编译时长度会自动转换为运行时长度。【参考方案2】:

您可以使用std::array::data() 成员函数将std::array 的内容作为原始的类C 数组指针简单地访问:

int* arrayPointer = useSeedPositions32 ? SeedPositions32.data() : SeedPositions16.data();

【讨论】:

【参考方案3】:

在他的回答中,juanchopanza 很好地解释了为什么你想要的东西行不通。

问题是您为什么要这样做?没有办法可以使用(指向)std::array&lt;int,32&gt; 来代替 std::array&lt;int,16&gt;

std::array&lt;&gt; 的重点是在编译时跟踪元素的数量(同时避免为固定大小的小型数组分配内存)。如果您希望在运行时管理元素的数量,您可能不应该使用std::array&lt;&gt;,而是使用std::vector

获取指向基础数据的指针(使用其他答案中提出的std::array::data())并自己跟踪元素数量的替代方法有点危险,并不值得推荐。问题是您必须确保指针永远不会悬空。

最后,我找不到任何可能的用例。为了使用您的指针,您必须同时声明 array&lt;int,32&gt;array&lt;int,16&gt; 对象,但只能使用其中一个。 为什么不简单地声明一个array&lt;int,32&gt; 并仅使用它的前 16 个元素(如果不需要全部 32 个元素)?

【讨论】:

array 的前 16 个元素与 array 中存储的不同。由于缺乏定位算法,我需要根据锦标赛中玩家的数量选择一组位置。在决定使用哪种解决方案之前,我将再次尝试一种算法。感谢您的帮助。【参考方案4】:

你可以这样做:

int * myArray = use32 ? &SeedPositions32[0] : &SeedPositions16[0];

【讨论】:

以上是关于如何声明指向 C++11 std::array 的指针?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++11 中具有对齐元素的 std::array 类型

std::vector 的 std:array 的 SFINAE 不能在 C++11 中编译

c++11 std::array vs 静态数组 vs std::vector

指向 std::array 成员的指针

C ++ 11中的数组[重复]

我们可以在 C++14 中省略 std::array 的双括号吗?