c++ - 如何将字符串列表存储在 constexpr 上下文中?

标签 c++ language-lawyer c++17 constexpr initializer-list

我一直在为某些域对象类转换这些文档字符串表(作为系统的类型特征),直到我偶然发现了这个问题。 后来,我打算在编译时检查这些特殊成员是否编写了文档(作为我在编译时喜欢它的原因)。 我创建了一个小示例用于演示:

https://godbolt.org/z/3dX3-e

#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 个主要编译器似乎以不同方式处理这种情况,这似乎适用于较旧的 , 但在更改为最新版本 9.1 时无法编译(说 cstr_test 行不是常量表达式)。在 (和我感兴趣的那个)initializer_list获得正确的大小,但临时文件无法保留到输出。 由于正在创建临时文件,因此拒绝编译。最后一件事似乎是一个提示,我怀疑这就是 可能发生的事情。也没有发出错误。

如果std::initializer_list<M>,这个例子可以修复更改为 M .

引用文献中的相关部分可能是:

The underlying array is a temporary array of type const T[N], in which each element is copy-initialized (except that narrowing conversions are invalid) from the corresponding element of the original initializer list. The lifetime of the underlying array is the same as any other temporary object, except that initializing an initializer_list object from the array extends the lifetime of the array exactly like binding a reference to a temporary (with the same exceptions, such as for initializing a non-static class member). The underlying array may be allocated in read-only memory.

如何在编译时创建包含字符串的对象列表?

最佳答案

std::initializer_list 不应用作存储。

所以在你的情况下,存储应该在类之外完成。可以使用常规 C 数组或 std::array

然后您的类(class)可能只能查看该数据。

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];
}

关于c++ - 如何将字符串列表存储在 constexpr 上下文中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56164280/

相关文章:

c++ - 我的 boost phoenix 惰性函数出了什么问题?

c++ - 在不捕获的情况下访问 lambda 表达式中的 constexpr 变量

c++ - 三字母仍然有效 C++ 吗?

c++ - 使用 FFMPEG 读取每帧时间码?

c++ - Makefile vpath 不适用于头文件

c - C 中的接口(interface)

c++ - 嵌套参数包扩展

c++ - 未自动确定的模板化类型的隐式转换运算符

c++ - 如何添加第三方库的路径? - Eclipse/Arduino

c++ - ISO C++ 说这些是模棱两可的,即使第一个最差的转换比第二个最差的转换要好