如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N>
Posted
技术标签:
【中文标题】如何使用省略尾随 \'\\0\' 的字符串文字初始化 std::array<char, N>【英文标题】:How to initialize a std::array<char, N> with a string literal omitting the trailing '\0'如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N> 【发布时间】:2015-11-02 18:16:27 【问题描述】:我有一个文件结构,其中固定长度的字符串没有尾随零。 如何将字段初始化为 std::array 而不尾随零:
#pragma pack(push, 1)
struct Data
// Compiles, but it has an undesired '\0':
std::array<char, 6> undesired_number"12345";
// Does not compile:
std::array<char, 5> number"12345"; // stripping '\0'
;
#pragma pack(pop)
【问题讨论】:
什么是编译器错误?不兼容的类型?恐怕基于字符串文字根本不可能。 为什么一定要用字符串字面量来初始化呢? @Barmar 只是为了方便 由于字符串文字总是附加'\0'
或等价物,我的赌注是一些中间的constexpr
/template 魔法,它会采用文字并去掉零并返回一个截断的值。但是它可能有问题,因为您不能修改字符串文字。也许常量表达式的例外允许它。
你可以制作一个用户定义的文字
【参考方案1】:
制作辅助函数
template <std::size_t N, std::size_t ... Is>
constexpr std::array<char, N - 1>
to_array(const char (&a)[N], std::index_sequence<Is...>)
return a[Is]...;
template <std::size_t N>
constexpr std::array<char, N - 1> to_array(const char (&a)[N])
return to_array(a, std::make_index_sequence<N - 1>());
然后
struct Data
std::array<char, 5> numberto_array("12345"); // stripping '\0'
;
Demo
【讨论】:
我想知道这是否会编译成文字的一个副本,或者两个,一个带有终止符,一个没有。 @luk32,取决于编译器和优化设置。例如,带有 O3 的 g++ 根本没有文字。 在获得make_index_sequence
并更改为std::array<char, 5> number = to_array("12345");
后与C++11 很好地配合
@VioletGiraffe: std::array
主要是struct T data[N]; ;
,所以在聚合初始化时,第一个括号是类array
,第二个是它的data
成员。 (一对可以省略,但编译器可能会警告“缺少”大括号)。
@303:使用默认可初始化类型,例如char
,您确实可以使用 for-range(即使从 C++14 开始(constexpr
函数中允许使用 for-range,并且std::array
的方法标记为 constexpr
))。您不能使用 for-range 初始化,只能分配/复制,这对 char
来说很好。【参考方案2】:
字符串文字是以 NUL 结尾的,在 C++ 中(与 C 不同),您不能通过提供 Length - 1
大小来取消它;因此它不能直接完成,同时考虑到array
内部是T[N]
。
【讨论】:
标准不要求array
在内部是 T[N]
。对于N > 0
的情况,有些人认为应该这样做以上是关于如何使用省略尾随 '\0' 的字符串文字初始化 std::array<char, N>的主要内容,如果未能解决你的问题,请参考以下文章