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

使用可变参数模板打印函数签名时丢失const限定符的问题排查

问题原因

当函数参数是值传递的const类型(顶层const)时,C++会将其视为与非const值参数等价的函数签名。在模板推导Ret(*)(Args...)时,编译器会自动丢弃顶层const,导致Args中的类型丢失了const限定符。

而手动调用print_function_args<const int>()时,模板参数直接指定为const int,没有经过函数类型推导的“顶层const丢弃”步骤,所以能正常识别const。

解决办法

通过自定义类型萃取工具,直接从函数的原始声明类型中提取参数类型(包括顶层const),避免依赖函数指针推导时的const丢失。

修改后的完整代码

#include <iostream>
#include <type_traits>
#include <tuple>

// 类型萃取工具:提取函数的参数和返回值类型
template <typename T>
struct function_traits;

// 匹配普通函数类型
template <typename Ret, typename... Args>
struct function_traits<Ret(Args...)> {
    static constexpr size_t arity = sizeof...(Args);
    using return_type = Ret;

    template <size_t N>
    using arg_type = std::tuple_element_t<N, std::tuple<Args...>>;
};

// 匹配函数指针类型
template <typename Ret, typename... Args>
struct function_traits<Ret(*)(Args...)> : function_traits<Ret(Args...)> {};

template <typename T>
void print_type_info() {
    if (std::is_const_v<T>) {
        std::cout << "const ";
    }
    std::cout << typeid(T).name() << std::endl;
}

// 递归打印参数类型的辅助函数
template <typename Traits, size_t N = 0>
void print_function_args_impl() {
    if constexpr (N < Traits::arity) {
        print_type_info<typename Traits::template arg_type<N>>();
        print_function_args_impl<Traits, N + 1>();
    }
}

template <typename Func>
void print_function_signature(Func) {
    using traits = function_traits<Func>;
    print_function_args_impl<traits>();
}

void my_function(int, const int) {}

int main() {
    print_function_signature(my_function); // 现在会打印'i'和'const i'
    print_function_args<const int>(); // 正常打印'const i'
    return 0;
}

修改说明

  1. 新增function_traits结构体,用于从函数类型/函数指针中提取参数类型,完整保留原始声明中的顶层const。
  2. 将print_function_signature改为接受任意函数类型的模板参数,通过function_traits获取参数类型,绕开了会丢失const的函数指针推导逻辑。
  3. 使用递归的print_function_args_impl遍历所有参数类型并完成打印。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 19:34:56