我一直在为某些域对象类转换这些docstring表(作为系统的类型特征),直到我遇到这个问题为止。 后来,我打算在编译时检查这些特殊成员是否编写了文档(作为为什么在编译时我想要它的原因)。 我创建了一个小示例进行演示:
#include <initializer_list>
struct CStr {
struct M {
const char* name;
const char* val;
};
constexpr CStr(const std::initializer_list<M>& str) : str_(str) {
};
std::initializer_list<M> str_;
};
constexpr CStr cstr_test{ { {"key", "val"} } };
int main() {
return cstr_test.str_.begin()->name[0];
}
基本上,这3个主要的编译器似乎对此情况有所不同,该似乎适用于较旧的gcc,但在更改为最新版本9.1时无法编译(说cstr_test行是而不是竞争的表达)。在msvc(和一个我感兴趣的人)上,initializer_list
的大小正确,但临时值无法保留到输出中。 clang由于被创建而拒绝编译。最后一件事似乎是一个提示,我怀疑msvc也会发生这种情况,但不会发出错误。
如果将std::initializer_list<M>
更改为M
,则示例可以固定。
参考文献中的相关部分可能是:
基础数组是类型为const T [N]的临时数组,其中 每个元素均已复制初始化(缩小转换范围除外) 是无效的) 初始化列表。基础数组的生存期与 任何其他临时对象,除了初始化 数组中的initializer_list对象延长了 数组完全类似于将引用绑定到临时(具有相同的 异常,例如用于初始化非静态类成员的异常)。的 基础数组可以分配在只读内存中。
如何在编译时创建包含字符串的对象列表?
答案 0 :(得分:1)
std::initializer_list
不应用作存储空间。
因此,在您的情况下,应在课程之外进行存储。可以使用常规的C数组或std::array
。
然后您上课可能只是查看了这些数据。
C ++ 20提供了std::span
。
在C ++ 20之前,您可能会做类似的事情:
struct CStr {
struct M {
const char* name;
const char* val;
};
constexpr CStr(const M* data, std::size_t size) : data(data), size(size) {}
const M* begin() const { return data; }
const M* end() const { return data + size; }
const M* data;
std::size_t size;
};
constexpr CStr::M data[]{ { {"key", "val"} } };
constexpr CStr cstr_test(data, 1);
int main() {
return cstr_test.begin()->name[0];
}
答案 1 :(得分:-1)