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

如何将带可变参数的成员函数作为函数模板参数传递?

可变参数成员函数模板callmv的正确调用方式

原代码及问题

原代码

struct Cla {
  void w(int x){}
};

template <typename C, void (C::*m)(int)> void callm(C *c, int args) {}

template <typename C, typename... A, void (C::*m)(A...)>
void callmv(C *c, A &&...args) {}

int main(){
  Cla cla; // 补充原代码遗漏的对象定义
  callm<Cla, &Cla::w>(&cla, 3); // 可正常编译
  callmv<Cla, int, &Cla::w>(&cla, 3); // 编译报错
}

编译错误信息

test.cpp: In function ‘int main()’:
test.cpp:84:28: error: no matching function for call to ‘callmv<Cla, int, &Cla::w>(Cla*, int)’
   84 |   callmv<Cla, int, &Cla::w>(&cla, 3);
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
test.cpp:52:6: note: candidate: ‘template<class C, class ... A, void (C::* m)(A ...)> void callmv(C*, A&& ...)’
   52 | void callmv(C *c, A &&...args) {}
      |      ^~~~~~
test.cpp:52:6: note:   template argument deduction/substitution failed:
test.cpp:84:28: error: type/value mismatch at argument 2 in template parameter list for ‘template<class C, class ... A, void (C::* m)(A ...)> void callmv(C*, A&& ...)’
   84 |   callmv<Cla, int, &Cla::w>(&cla, 3);
      |   ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~
test.cpp:84:28: note:   expected a type, got ‘&Cla::w’

错误原因

模板参数的规则限制导致:

  • typename... A是模板类型参数包,要求后续匹配的参数必须是类型;
  • void (C::*m)(A...)是模板非类型参数(成员函数指针值)。
    当显式指定callmv<Cla, int, &Cla::w>时,编译器会将int识别为A的一部分,接着期望下一个参数是类型,但&Cla::w是具体值,因此触发“类型/值不匹配”错误。

正确调用方式

方式1:利用模板参数推导(推荐)

无需显式指定A的类型,编译器会通过函数实参3自动推导A为int,同时匹配成员函数指针的参数列表:

callmv<Cla, &Cla::w>(&cla, 3);

方式2:调整模板定义(C++17及以上)

改用auto非类型参数简化模板,彻底避免参数顺序问题:

#include <type_traits>

template <typename C, auto m>
void callmv(C *c, std::invoke_result_t<decltype(m), C*, int>&&... args) {
    (c->*m)(std::forward<decltype(args)>(args)...);
}

// 调用写法更简洁
callmv<Cla, &Cla::w>(&cla, 3);

内容的提问来源于stack exchange,提问作者Fabio Dalla Libera

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 07:40:35