一段时间以来,我一直很高兴地在我的代码中使用以下样式的常量字符串文字,但并没有真正理解它是如何工作的:
constexpr std::array myStrings = { "one", "two", "three" };
这可能看起来微不足道,但我对幕后发生的事情的细节一无所知。根据我的理解,类模板参数推导 (CTAD) 用于构造适当大小和元素类型的数组。我的问题是:
- 在这种情况下,std::array 的元素类型是什么,或者这个实现是特定的?查看调试器(我使用的是 Microsoft C++),元素只是指向非连续位置的指针。
- 以这种方式声明字符串文字的 constexpr 数组是否安全?
我可以改为这样做,但它不是那么整洁:
const std::array<std::string, 3> myOtherStrings = { "one", "two", "three" };
最佳答案
是的,这是 CTAD 为您推导模板参数。 (C++17 起)
std::array
有一个deduction guide它使用这种形式的初始化程序启用 CTAD。
它将推断出 myStrings
的类型到
const std::array<const char*, 3>
const char*
是将通常的数组到指针衰减应用于初始化列表的元素(它们是 const char
s 的数组)的结果。
const
前面是 constexpr
的结果.
数组的每个元素都会指向相应的字符串字面值。
constexpr
是安全的,您可以像通过 const char*
使用单独的字符串文字一样使用数组元素指针。特别是试图通过 const_cast
修改这些文字或数组但是会有未定义的行为。
const std::array<std::string, 3>
也可以,但不能用于常量表达式。 constexpr
因为 std:string
不允许这样做.
虽然在字符串文字运算符的帮助下,CTAD 也可用于推断此类型:
#include<string>
using namespace std::string_literals;
//...
const std::array myOtherStrings = { "one"s, "two"s, "three"s };
或者从 C++20 开始:
const auto myOtherStrings = std::to_array<std::string>({ "one", "two", "three" });
关于C++ constexpr std::array of string literals 字符串文字数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71882752/