类内可变参数模板嵌套类能否设默认参数并访问类实例?
问题分析与可行实现方案
原代码的核心问题在于:嵌套结构体无法像成员函数那样直接通过类实例调用,且类内模板推导指引不能使用this参数。以下是两种既能保留可变参数模板、默认参数,又能访问类实例的实现方式:
方案一:将running_func改为类的成员模板函数
这是最简洁直接的实现方式,成员函数天然具备访问this的能力,同时完全保留原有的可变参数与默认参数特性:
#include <iostream> #include <utility> inline static constexpr auto myrun_func = [](auto b){std::cout<<b<<std::endl;}; class foo{ public: template<class UnaryFunction, class... Args> void running_func(UnaryFunction&& unary, Args... args, const char* str = __builtin_FUNCTION()){ std::cout<<"function was run from "<<str<<std::endl; std::forward<UnaryFunction>(unary)(args...); this->f(); } private: void f(){ std::cout<<"f() called"<<std::endl; } }; void test(){ foo example; example.running_func(myrun_func, 10); } int main() { test(); return 0; }
运行输出
function was run from test() 10 f() called
说明
- 直接将原嵌套结构体改为成员模板函数,无需额外传递类实例指针,通过
this即可访问私有成员f()。 - 调用方式与全局版本完全一致,参数推导和默认参数均正常生效。
方案二:保留嵌套结构体,通过工厂函数封装构造逻辑
若必须保留running_func作为嵌套结构体,可以添加一个工厂成员函数,自动将this指针传递给结构体构造函数:
#include <iostream> #include <utility> inline static constexpr auto myrun_func = [](auto b){std::cout<<b<<std::endl;}; class foo{ public: template<class UnaryFunction, class... Args> struct running_func{ running_func(foo* ex, UnaryFunction&& unary, Args... args, const char* str = __builtin_FUNCTION()){ std::cout<<"function was run from "<<str<<std::endl; std::forward<UnaryFunction>(unary)(args...); ex->f(); } }; // 工厂函数:自动传入this,转发所有参数 template<class UnaryFunction, class... Args> auto make_running_func(UnaryFunction&& unary, Args... args) { return running_func<UnaryFunction, Args...>(this, std::forward<UnaryFunction>(unary), std::forward<Args>(args)...); } private: void f(){ std::cout<<"f() called"<<std::endl; } }; void test(){ foo example; example.make_running_func(myrun_func, 10); } int main() { test(); return 0; }
运行输出
与方案一完全一致。
说明
- 嵌套结构体的构造函数仍需接收类实例指针,但无需用户手动传入,由工厂函数自动处理。
- 通过完美转发参数保证语义正确性,同时保留可变参数和默认参数的特性。
内容的提问来源于stack exchange,提问作者Sam Moldenha
相关产品推荐
相关产品推荐

