我使用Visual C ++ 2012.我想使用指向另一个函数的指针来参数化模板函数。这一切都在课堂之外很好地运作:
int add(int a, int b) {
return a + b;
}
typedef int (*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return F(a, b);
}
int foo(int a, int b) {
return do_it<add>(a, b);
}
Visual C ++ 2012可以完美地编译和优化它。
现在,我把它放在一个类中并调整指针指向成员:
struct S {
int add(int a, int b) {
return a + b;
}
typedef int (S::*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return F(a, b); // <-- here be error!
}
int foo(int a, int b) {
return do_it<&S::add>(a, b);
}
};
S s;
int bar(int a, int b) {
return s.foo(a, b);
}
但是这给了我一个编译错误:
Microsoft (R) C/C++ Optimizing Compiler Version 17.00.51106.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
x2.cpp
x2.cpp(7) : error C2064: term does not evaluate to a function taking 2 arguments
x2.cpp(10) : see reference to function template instantiation 'int S::do_it<int S::add(int,int)>(int,int)' being compiled
知道为什么以及如何解决它?
答案 0 :(得分:4)
成员指针的语法仍然适用。你应该写:
typedef int (S::*func)(int a, int b);
template<func F> int do_it(int a, int b) {
return (this->*F)(a, b);
}
使用指向成员的指针总是需要将对象与它相关联 - 在这里,您可以在this
上调用指针。
答案 1 :(得分:2)
必须在对象上调用成员函数指针;与普通的成员函数调用不同,必须明确指定this
:
(this->*F)(a,b);
虽然,如果函数不需要访问this
,也许它应该是静态的(或非成员),由普通函数指针指定。
答案 2 :(得分:1)
看起来您只需要在对象上调用成员函数指针:
template<func F> int do_it(int a, int b) {
return (this->*F)(a, b);
}
对于成员的指针总是需要在一个对象上调用,这与自由和静态成员函数不同,这就是你需要上述语法的原因。
答案 3 :(得分:1)
调用指向成员指针的函数时需要提供对象:
(this->*F)(a, b);
答案 4 :(得分:0)
进一步说明:将“do_it”更普遍地写为
template<class F> int do_it(F f, int a, int b) {
return f(a, b); }
现在,你可以传递两个整数的任何函数:
int mul(int a, int b) { return a*b ; }
S s;
s.do_it(mul,2,3);
当您打算在类中使用成员函数时,只需将其与此绑定即可。使用boost :: bind,
int foo(int a, int b) {
return do_it( boost::bind(&S::add,this,_1,_2),a,b) ;