初始化一个由 std::pair 组成的 constexpr std::array

8
在C++14中,我如何初始化一个包含文本字符串的全局constexpr std::pairstd::array?以下代码无法工作:
#include <array>

constexpr std::array<std::pair<int, const char[]>, 3> strings = {
  {0, "Int"},
  {1, "Float"},
  {2, "Bool"}};

int main() {
}
2个回答

14
你已经接近成功了。首先,char const[] 类型需要改为指针类型,因为它是不完整的类型,可能无法保存在 std::pair 中。其次,你缺少一对花括号。正确的声明应该像这样:
constexpr std::array<std::pair<int, const char*>, 3> strings = {{
  {0, "Int"},
  {1, "Float"},
  {2, "Bool"},
}};

额外的大括号是必需的,因为std::array是一个持有原始C数组的聚合体,因此我们需要显式地使用大括号来表示{0,"Int"}不会错误地被当作内部数组对象的初始化器。


为什么C++14中放宽的聚合初始化在这里不起作用?std :: array <std :: string,2> s = {“Hi”,“Hello”};std :: array <std :: string,2> s = {{“Hi, “Hello”}};在C++14之后被认为是相同的(对于非constexpr数组)。为什么这里不适用同样的规则? - aep
1
@aep - 大括号省略算法在初始化第一对而不是内部数组时存在问题。 - StoryTeller - Unslander Monica
1
我觉得经过一些实验,我现在理解了它们之间的区别。我尝试了一些组合,比如 std::array<std::string, 2> s={"hi", "hello"};std::array<std::string, 2> s={{"hi", "hello"}};std::array<std::string, 2> s={{"hi"}, {"hello"}};std::array<std::string, 2> s={{{"hi"}, {"hello"}}}; 来看看它们之间的差异。感谢您的解释。 - aep

0
在C++20中的一种替代方法是使用std::to_array,它允许您创建一个数组,而无需事先指定大小。
constexpr auto strings = std::to_array<std::pair<int, const char*>>({
{0, "Int"},
{1, "Float"},
{2, "Bool"},
});

std::to_array 在这里的效益是值得怀疑的。如果你的答案针对 C++20,你可能还应该使用 std::string_view 而不是 const char*。在某些情况下,拥有大小信息可以大大提升性能。 - undefined

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