如何去除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); // 直接调用,无需后缀或模板尖括号 }
原理说明
consteval构造函数:确保fixed_string只能由编译期已知的字符串字面量构造,排除运行时字符串的可能性,保证参数可作为非类型模板参数。- 模板参数推导:函数模板的占位参数
decltype(s) = {}允许编译器通过传入的字符串字面量,自动推导非类型模板参数s的具体值。 - 编译期可用性:
s作为非类型模板参数,在函数内部是完全的编译期常量,可用于constexpr计算、static_assert、if constexpr等编译期逻辑。
内容的提问来源于stack exchange,提问作者zodd
相关产品推荐
相关产品推荐

