如何用C++20的constexpr替代依赖其他宏的#define定义?
在C++20中用constexpr实现字符串拼接替代#define
原宏定义的字符串拼接是预处理器层面的特性——XX "yy"会在预处理阶段直接合并成"xxyy",但constexpr变量是编译期实体,没法直接用这种字面量拼接语法。以下是几种C++20下的可行方案:
方案1:匿名constexpr lambda直接拼接
最直观的方式是用编译期lambda完成字符复制,生成拼接后的std::string_view:
#include <string_view> #include <algorithm> constexpr std::string_view XX = "xx"; constexpr std::string_view XXYY = []() constexpr { // 计算所需缓冲区大小:XX的长度 + "yy"的长度 + 终止符 char buf[XX.size() + 2 + 1]{}; std::copy(XX.begin(), XX.end(), buf); std::copy("yy", "yy" + 2, buf + XX.size()); return std::string_view(buf, XX.size() + 2); }();
lambda会在编译期执行,直接生成拼接后的字符串视图,运行时无额外开销。
方案2:通用编译期拼接模板
如果需要频繁拼接多个字符串,可以写一个通用模板函数,复用性更强:
#include <string_view> #include <array> #include <algorithm> template<std::string_view... Strings> constexpr auto concat_strings() { constexpr size_t total_len = (Strings.size() + ...); std::array<char, total_len + 1> buffer{}; auto iter = buffer.begin(); // 折叠表达式依次复制每个字符串的字符 ((iter = std::copy(Strings.begin(), Strings.end(), iter)), ...); return std::string_view(buffer.data(), total_len); } // 定义基础字符串 constexpr std::string_view XX = "xx"; // 调用模板拼接XX和"yy" constexpr std::string_view XXYY = concat_strings<XX, "yy">();
这个模板支持任意数量的std::string_view或字符串字面量拼接,编译期就能计算出总长度并完成复制。
方案3:手动编译期字符复制
如果场景简单,也可以直接手动在编译期复制字符,逻辑更直白:
#include <string_view> constexpr std::string_view XX = "xx"; constexpr std::string_view XXYY = []() constexpr { char buf[5]{}; // "xxyy"共4个字符,加终止符占5位 buf[0] = XX[0]; buf[1] = XX[1]; buf[2] = 'y'; buf[3] = 'y'; return std::string_view(buf, 4); }();
这种写法适合固定长度的简单拼接,不需要依赖算法库。
所有方案的核心都是在编译期完成字符的复制与拼接,既避免了预处理器宏的无类型检查、意外替换等弊端,又保持了编译期计算的性能优势。
内容的提问来源于stack exchange,提问作者Thomas W.
相关产品推荐
相关产品推荐

