如何在constexpr上下文从整数字面量/ASCII码或G++#embed创建std::string_view?
解决G++中#embed生成constexpr std::string_view的单行实现问题
在启用G扩展时,G支持在C++中使用#embed指令,该指令能将文件内容转换为字节序列(比如字符串"ABC"会转为65, 66, 67)。我需要在constexpr上下文生成std::string_view,最终用于构建frozen::unordered_map。
在C语言中可以这样实现:
const char test[] = { #embed <blub.obj> , 0};
这等效于const char test[] = {65, 66, 67, 0};。但在C++中我目前只能通过定义两个变量的方式实现:
#include <array> #include <iostream> #include <string_view> static constexpr std::array arr = std::to_array<char>({65, 66, 67}); static constexpr std::string_view sv(arr.data(), arr.size()); int main() { std::cout << sv << std::endl; }
希望能找到在新版G++中用一行代码实现的方式,避免当前通过CMakeLists.txt生成#define的不优雅方案。
单行实现方案
借助C++20的constexpr lambda特性,可以将数组定义与std::string_view构造封装在一个表达式中,仅需一个变量定义:
#include <string_view> #include <array> // 单行定义constexpr std::string_view static constexpr std::string_view sv = []() constexpr { constexpr auto arr = std::to_array<char>({#embed <blub.obj>}); return std::string_view(arr.data(), arr.size()); }();
细节说明
constexprlambda会在编译期执行,内部的arr是编译期生成的静态数组,存储#embed导入的字节序列- 返回的
std::string_view指向该静态数组,生命周期与程序一致,完全满足constexpr上下文要求 - 如果需要兼容C风格终止符(比如原内容是文本且需要
\0结尾),可以调整为:static constexpr std::string_view sv = []() constexpr { constexpr auto arr = std::to_array<char>({#embed <blub.obj>, 0}); return std::string_view(arr.data(), arr.size() - 1); // 可选:去掉末尾的0,保留实际内容长度 }(); - 若要在多编译单元中共享该变量,可将
static替换为inline,避免重定义问题。
内容的提问来源于stack exchange,提问作者Torsten Knodt
相关产品推荐
相关产品推荐

