You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在模板参数中分离函数类型的返回值与参数?

解决直接传递函数类型给类模板以分离返回值与参数的问题

你遇到的问题核心是模板参数的匹配逻辑:原模板template<typename R, typename... Args>会把你传入的int(float)整个当成R的类型,不会自动拆分返回值和参数。要实现直接传递函数类型并拆分出返回值与参数,我们可以通过类模板的偏特化来解决——完全不需要依赖函数指针,而且兼容C11到C17的版本。

具体实现方案

我们先定义一个空的主模板占位,然后针对函数类型做偏特化,让模板自动从传入的函数类型中提取返回值R和参数列表Args...

#include <iostream>
#include <utility>

// 主模板:仅作为占位,用于匹配后续的特化版本
template<typename Func>
class CallFunction;

// 针对函数类型的偏特化:自动拆分返回值R和参数Args...
template<typename R, typename... Args>
class CallFunction<R(Args...)> {
public:
    R operator()(Args&&... args) {
        // 修复原代码的折叠表达式写法,正确输出每个参数
        (std::cout << args << "\n", ...);
        return R{100};
    }
};

int main() {
    // 直接传入函数类型int(float),模板会自动解析R=int,Args=[float]
    CallFunction<int(float)> cf;
    std::cout << "return value: " << cf(200.f) << "\n";
    return 0;
}

代码细节说明

  1. 主模板的作用template<typename Func> class CallFunction; 是一个空模板,当我们传入int(float)这种函数类型时,编译器会自动匹配下面的偏特化版本,而不会尝试实例化主模板。
  2. 偏特化的匹配逻辑template<typename R, typename... Args> class CallFunction<R(Args...)> 专门针对函数类型设计,这里的R(Args...)会直接对应你传入的int(float),自动将R推导为intArgs...推导为float
  3. operator()的调整:原代码中的折叠表达式("" << ... << (args << "\n"))存在编译问题,空字符串无法直接和args << "\n"的结果拼接。我们改用逗号运算符的折叠表达式(std::cout << args << "\n", ...),依次输出每个参数并换行,这是C++17支持的标准写法。

运行效果

编译运行后,输出结果如下:

200
return value: 100

完全符合你的需求:直接传递函数类型,模板正确分离返回值和参数,且不需要依赖任何函数指针或decltype的额外处理。

内容的提问来源于stack exchange,提问作者void.pointer

火山引擎 最新活动