You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++17如何用constexpr替换字符串字面量拼接的预处理器宏

C++17 替换字符串字面量拼接宏的实现方案

原宏依赖预处理器对相邻字符串字面量的自动拼接能力,C++17可以通过constexpr构造编译期字符串结构实现完全等价的零开销替换,不需要保留任何预处理器宏。

实现步骤

  • 首先实现一个轻量的编译期固定长度字符串工具,支持constexpr语境下的拼接操作:
#include <array>
#include <utility>
#include <string_view>

template<std::size_t N>
struct ConstStr {
    std::array<char, N> buffer{};

    // 支持从字符串字面量隐式构造
    constexpr ConstStr(const char (&str)[N]) {
        for (std::size_t i = 0; i < N; ++i) {
            buffer[i] = str[i];
        }
    }

    // 拼接场景的内部构造函数
    constexpr ConstStr(std::string_view sv, std::integral_constant<std::size_t, N>) {
        for (std::size_t i = 0; i < sv.size(); ++i) {
            buffer[i] = sv[i];
        }
        buffer[N - 1] = '\0';
    }

    // 兼容C风格字符串和string_view使用场景
    constexpr const char* c_str() const noexcept { return buffer.data(); }
    constexpr operator std::string_view() const noexcept { return {buffer.data(), N - 1}; }
};

// constexpr拼接运算符重载
template<std::size_t N1, std::size_t N2>
constexpr auto operator+(const ConstStr<N1>& a, const ConstStr<N2>& b) {
    std::array<char, N1 + N2 - 1> tmp{};
    std::size_t pos = 0;
    for (std::size_t i = 0; i < N1 - 1; ++i) tmp[pos++] = a.buffer[i];
    for (std::size_t i = 0; i < N2 - 1; ++i) tmp[pos++] = b.buffer[i];
    tmp[pos] = '\0';
    return ConstStr<N1 + N2 - 1>(tmp.data(), std::integral_constant<std::size_t, N1 + N2 - 1>{});
}
  • 直接替换原有宏定义和数组声明,所有逻辑均在编译期执行:
// 替换原#define FNAME "first"
constexpr ConstStr FNAME = "first";
// 替换原#define LNAME "last"
constexpr ConstStr LNAME = "last";
// 替换原#define NAME FNAME LNAME
constexpr auto NAME = FNAME + LNAME;
// 替换原const char hello[] = "hello " NAME;
constexpr auto hello = ConstStr("hello ") + NAME;

效果说明

  • 所有拼接计算完全在编译阶段完成,和原宏实现相比没有任何运行时开销,生成的二进制内容完全一致
  • hello.c_str()可以直接获取到const char*类型的C风格字符串,和原代码中hello数组的使用方式完全兼容
  • 全程使用C++17标准特性:constexpr、类模板、std::array、std::string_view、运算符重载,没有任何宏定义参与
  • 如果仅需要临时读取字符串内容、不需要持有字符数组,可以直接用std::string_view做编译期拼接,不需要自定义ConstStr结构,但该方式无法直接生成全局可用的C风格字符数组。

内容的提问来源于stack exchange,提问作者Baruch

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:24:19