如何将 C 风格的编译时数组转换为 std::array

在我们的资料中,我们经常有这样的事情:

static const int g_numbers[]{ 1, 2, 3, 4, 5};
static const struct
{
    const int         m_nID;
    const char* const m_pszName;
}
g_collection[]
{
    { 1, "Max" },
    { 2, "Fabian" },
    { 3, "Martin" },
    …
};

如何将这些编译时数组转换为现代 C++?使用例如std::array

如果我理解正确, std::array 需要一个大小作为模板参数。

您建议采用哪种方式以最小的开销(例如代码生成)和不必要的冗余信息来转换此类代码?

回答

你有一个选择。要么使用模板参数推导,要么自己指定参数。

使用模板参数推导:

static constexpr std::array g_numbers{1, 2, 3, 4, 5};
struct g_collection_element
{
int         m_nID;
char const* m_pszName;
};
static constexpr std::array g_collection{
g_collection_element{ 1, "Max" },
g_collection_element{ 2, "Fabian" },
g_collection_element{ 3, "Martin" },
};

正如你在这里看到的,我命名了结构并在声明后使用它。我还从成员中删除了 const,因为在这种情况下它们并没有真正的用处。

此外,要使模板参数推导工作,您必须为数组中的每个初始值设定项键入元素的类型,否则编译器将不会执行模板参数推导。

指定参数:

static constexpr std::array<int, 5> g_numbers{1, 2, 3, 4, 5};
struct g_collection_element
{
int         m_nID;
char const* m_pszName;
};
static constexpr std::array<g_collection_element, 3> g_collection{
{ 1, "Max" },
{ 2, "Fabian" },
{ 3, "Martin" },
};

遗憾的是,您不能只指定类型来推导数字。


为了用 C++20 解决方案补充另一个答案(尽管 C++17 上限),您可以elem使用std::to_array

static constexpr auto g_collection = std::to_array<elem>(
{
{ 1, "Max" },
{ 2, "Fabian" },
{ 3, "Martin" },
});

指定elem一次,并保留要推断的大小。由于类型是显式提供的,因此不需要再输入大括号初始值设定项。

这可能看起来像是在创建两个对象(一个临时原始数组和一个静态 std::array),但由于不断评估的优点,这被折叠成一个硬编码对象。


以上是如何将 C 风格的编译时数组转换为 std::array的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>