代码之家  ›  专栏  ›  技术社区  ›  darune

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

  •  0
  • darune  · 技术社区  · 6 年前

    我正在为一些域对象类转换这些docstring表(作为类型特征,如system),直到我在这个问题上遇到困难。 后来,我计划在编译时检查这些特殊成员是否编写了文档(这是为什么我希望在编译时编写文档的原因)。

    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_测试行不是contant表达式)。打开 )那个 initializer_list 获取正确的大小,但临时值不存在于输出中。 由于临时创建,拒绝编译。最后一件事似乎是个暗示,我怀疑这是可能发生的 也没有错误。

    std::initializer_list<M> 改为 M .

    参考文献中的相关章节可能是:

    每个元素都被复制初始化(除了缩小转换范围 初始值设定项列表。底层数组的生存期与 任何其他临时对象,除了初始化 数组中的初始值设定项列表对象延长 异常,例如初始化非静态类成员)。这个 底层数组可以在只读内存中分配。

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

    0 回复  |  直到 6 年前
        1
  •  1
  •   Jarod42    6 年前

    std::initializer_list 不应用作存储。

    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];
    }
    
        2
  •  -1
  •   Marek R    6 年前

    它有点不同的方法(IMO,你的例子太复杂),但是C++ 17介绍 std::string_view 所以这可以用简单的方法来处理,而不需要额外的类。另外,当您不知道有多少个元素时,可以使用类似于C的数组:

    const constexpr std::pair<std::string_view, std::string_view> str_test[] {
        { "a"sv, "alpha"sv },
        { "b"sv, "beta"sv },
        { "c"sv, "siera"sv },
    };
    

    现场演示 gcc clang msvc .