如何在C++可变模板中正确展开参数以调用指定形式的foo函数?
解决模板参数包递减展开问题
你的核心问题是无法让模板参数包按递减长度展开(从A<Args...>到A<Args的前n-1个>…直到空特化),原代码中A<V>::m...是无效写法,且无法实现预期的层级展开。下面是正确的实现方式:
修正后的代码
#include <utility> // 用于std::forward void foo(int x, int y, int z) { // 可根据需求实现函数逻辑 } template<typename... Args> class A; // 空特化:递归终止点,负责最终调用foo template<> class A<> { public: void call(auto&&... args) { foo(std::forward<decltype(args)>(args)...); } }; template<typename T, typename... Args> class A<T, Args...> : public A<Args...> { public: A() = default; // 完美转发构造参数,初始化当前成员和基类 A(T a, Args... v) : m(a), A<Args...>(std::forward<Args>(v)...) {} void call() { // 传递当前类的m给基类的call,触发递归展开 A<Args...>::call(m); } T m; }; int main() { A<int, int, int> a{1, 2, 3}; a.call(); // 实际调用 foo(1, 2, 3),对应你期望的 foo(m, A<int,int>::m, A<int>::m) }
原理说明
- 递归特化:通过
A<>空特化作为递归终止点,每个A<T, Args...>继承自A<Args...>,形成层级结构。 - 参数传递递归:
A<T, Args...>::call()会将自身的m传递给基类A<Args...>::call(),基类再传递自己的m给更上层基类,直到A<>::call()收集所有参数并调用foo。 - 完美转发:构造函数中使用
std::forward确保参数传递的正确性,避免不必要的拷贝。
如果你的foo确实需要4个参数,只需将A的实例改为A<int, int, int, int> a{1,2,3,4},即可自动展开为4个参数的调用。
内容的提问来源于stack exchange,提问作者OhWizz3
相关产品推荐
相关产品推荐

