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
相关产品推荐
相关产品推荐

