指向成员的指针作为模板参数

时间:2013-09-02 12:35:16

标签: c++ templates function-pointers member-function-pointers pointer-to-member

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

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

5 个答案:

答案 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)  ;
相关问题