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

如何去除C++函数调用的_fs后缀,实现简洁的非类型模板参数传递?

问题描述

希望在C++中以普通函数调用风格(如test_normal_function("asd", x))传递字符串字面量作为非类型模板参数,避免使用test_normal_function2<"asd">(x)的模板尖括号写法,也无需依赖_fs后缀。

解决方案

利用C++20的consteval构造函数和模板参数推导特性,可以实现该需求。核心思路是让字符串字面量能隐式转换为编译期常量类型,从而让编译器自动推导函数模板的非类型参数:

#include <algorithm>
#include <array>

template <std::size_t N>
struct fixed_string 
{
    // consteval构造函数,确保仅编译期字符串可初始化该类型
    consteval fixed_string(const char (&foo)[N]) 
    {
        std::copy_n(foo, N, data.begin());
    }
    
    std::array<char, N> data{};
};

// 推导指引:自动根据字符串字面量长度推导fixed_string的模板参数
template <std::size_t N>
fixed_string(const char (&str)[N]) -> fixed_string<N>;

// 函数模板:用非类型模板参数接收编译期字符串,占位参数用于推导
template<fixed_string s>
void test_normal_function([[maybe_unused]] decltype(s) = {}, int x )
{
    // s是编译期常量,可直接用于编译期逻辑
    constexpr auto string_length = s.data.size() - 1;
    static_assert(string_length == 3, "字符串长度应为3");
    
    // 业务逻辑示例
    if constexpr (string_length == 3) {
        // 针对长度为3的字符串做编译期分支
    }
}

int main()
{
    int x = 3;
    test_normal_function("asd", x); // 直接调用,无需后缀或模板尖括号
}

原理说明

  1. consteval构造函数:确保fixed_string只能由编译期已知的字符串字面量构造,排除运行时字符串的可能性,保证参数可作为非类型模板参数。
  2. 模板参数推导:函数模板的占位参数decltype(s) = {}允许编译器通过传入的字符串字面量,自动推导非类型模板参数s的具体值。
  3. 编译期可用性:s作为非类型模板参数,在函数内部是完全的编译期常量,可用于constexpr计算、static_assert、if constexpr等编译期逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 14:15:41