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

C++模板类报错function returning a function,日志器实现求助

问题解决:Logger模板类报错"function returning a function"

错误原因

你调用Logger3<int(int,int)>(add,"test")时,模板参数传递逻辑错误:

  • 原模板定义为template<typename R, typename... Args>,第一个模板参数R被你传入的int(int,int)(完整函数类型)绑定,而非预期的返回值类型int。
  • 此时Args...为空参数包,导致function<R(Args...)>被解析为function<int(int,int)()>——这是一个返回函数类型的函数,C++不允许这种类型存在,因此触发编译错误。

修复方案

方案1:明确指定模板参数

直接按模板定义的要求,分别传入返回值类型和参数类型:

auto caller = Logger3<int, int, int>(add, "test");

方案2:优化模板类,自动推导参数(更优雅)

修改模板类或添加工厂函数,让编译器自动推导函数的返回值和参数类型,避免手动指定的麻烦:

方式A:基于原模板添加工厂函数

保留原模板结构,新增一个模板工厂函数自动推导参数:

#include <functional>
#include <string>
#include <iostream>

template <typename R, typename... Args>
class Logger3
{
public:
    Logger3(std::function<R(Args...)> func, const std::string& name):
        func{func}, name{name}
    {}
    R operator() (Args ...args)
    {
        std::cout << "Entering " << name << std::endl;
        R result = func(args...);
        std::cout << "Exiting " << name << std::endl;
        return result;
    }
private:
    std::function<R(Args...)> func;
    std::string name;
};

// 新增工厂函数,自动推导模板参数
template<typename R, typename... Args>
Logger3<R, Args...> make_logger(std::function<R(Args...)> func, const std::string& name) {
    return Logger3<R, Args...>(func, name);
}

// 调用示例
int add(int a, int b)
{
    std::cout << "Add two value" << std::endl;
    return a+b;
}

int main() {
    auto caller = make_logger(add, "test");
    caller(1, 2); // 输出日志并返回3
    return 0;
}

方式B:重构模板类,直接接受函数类型

彻底重构模板类,让它直接接收函数类型作为模板参数,通过类型推导简化使用:

#include <functional>
#include <string>
#include <iostream>
#include <utility> // 用于std::forward

template<typename Func>
class Logger3 {
public:
    Logger3(Func func, const std::string& name) : func(std::move(func)), name(name) {}

    // 自动推导返回值类型,支持完美转发参数
    template<typename... Args>
    auto operator()(Args&&... args) -> decltype(auto) {
        std::cout << "Entering " << name << std::endl;
        auto result = std::invoke(func, std::forward<Args>(args)...);
        std::cout << "Exiting " << name << std::endl;
        return result;
    }

private:
    Func func;
    std::string name;
};

// 工厂函数进一步简化调用
template<typename Func>
auto make_logger(Func func, const std::string& name) {
    return Logger3<Func>(std::move(func), name);
}

// 调用示例
int add(int a, int b) {
    std::cout << "Add two value" << std::endl;
    return a + b;
}

int main() {
    auto caller = make_logger(add, "test");
    caller(1, 2);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 00:39:17