2

我使用 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

知道为什么以及如何解决它吗?

4

5 回答 5

4

指向成员的指针的语法仍然适用。你应该写:

typedef int (S::*func)(int a, int b);
   template<func F> int do_it(int a, int b) {
      return (this->*F)(a, b);
   }

使用指向成员的指针总是需要将一个对象与它关联起来——在这里,你可以调用你的指针 on 是有道理的this

于 2013-09-02T12:39:07.363 回答
2

必须在对象上调用成员函数指针;与普通的成员函数调用不同,this必须明确指定:

(this->*F)(a,b);

虽然,如果函数不需要访问this,也许它应该是静态的(或非成员),由普通函数指针指定。

于 2013-09-02T12:39:33.363 回答
1

看起来您只需要在对象上调用成员函数指针:

template<func F> int do_it(int a, int b) {
      return (this->*F)(a, b);
}

指向成员的指针总是需要在对象上调用,这与自由和静态成员函数不同,这就是您需要上述语法的原因。

于 2013-09-02T12:39:20.113 回答
1

调用指向成员的函数时需要提供对象:

(this->*F)(a, b);
于 2013-09-02T12:40:49.680 回答
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);

当你打算在你的类中使用它的成员函数时,只需将它与 this 绑定。使用 boost::bind,

   int foo(int a, int b) {
       return do_it( boost::bind(&S::add,this,_1,_2),a,b)  ;
于 2013-09-02T13:24:21.447 回答