假设有以下定义
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(){
callm<Cla, &Cla::w>(&cla, 3);
callmv<Cla, int, &Cla::w>(&cla, 3);
}
第一个函数(callm)没问题。但是第二个函数(callmv)无法编译,g++会给出以下错误信息:
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’
什么是正确的语法?(我已经检查过将方法作为可变模板参数)
m
作为auto
非类型模板参数,并在模板中使用std::invoke
。您不需要关心它的类型。 - user17732522callmv<Cla, decltype(&Cla::w), &Cla::w>(&cla, 3)
(以及template <typename C, typename M, M m, typename... A>
)这样的东西,尽管您可以摆脱第一个Cla
。它可以从M
中获取或者如果在列表中的M m
之后,则可以从&cla
中推断出来。 - user17732522