【问题标题】:How to define and set a funtion pointer to a template class method如何定义和设置指向模板类方法的函数指针
【发布时间】:2018-06-13 12:42:41
【问题描述】:

我需要将作为模板类 X 的方法的函数指针变量设置为 X 的方法。

这是一个简单的例子。

X.h:

template<typename T>
class X {
public:
    typedef T (*valproc)(T v);

    X(T v);

    T add(T v);
    T val;
    valproc curproc;
};

X.cpp:

#include  "X.h"

template<typename T>
X<T>::X(T v) : val(v) {
    curproc = &X<T>::add;
}

template<typename T>
T X<T>::add(T v) {
    return v+val;
}

int main (int iArgC, char *apArgV[]) {
    X<int> *p = new X<int>(3);

    return  p->curproc(7);
}

当我编译这个时,我得到一个错误:

$ g++ -c -g -Wall X.cpp
X.cpp: In instantiation of 'X<T>::X(T) [with T = int]':
X.cpp:15:29:   required from here
X.cpp:5:13: error: cannot convert 'int (X<int>::*)(int)' to 'X<int>::valproc {aka int (*)(int)}' in assignment
     curproc = &X<T>::add;

显然

int (X::* )(int)
与
int (*)(int)
不一样

如何定义正确的类型?

【问题讨论】:

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


    【解决方案1】:

    X&lt;int&gt;::add 是一个非静态成员函数。这意味着&amp;X&lt;int&gt;::add 具有int(X&lt;int&gt;::*)(int) 类型:指向X&lt;int&gt; 的非静态成员函数的指针采用单个int 参数并返回int。这样的指针无法转换为int(*)(int)。

    int(X&lt;int&gt;::*)(int) 在概念上更类似于int(*)(X&lt;int&gt;*, int),而不是int(*)(int)(尽管根据平台的调用约定或inheritance is involved,实现实际上可能有很大不同)。它需要一个额外的隐藏X&lt;int&gt;* 参数:this 指针。

    做你想做的最简单的方法是使用包装方法:

    template<typename T>
    class X {
    public:
        using valproc = T(X::*)(T v);
    
        X(T v)
            : val{v},
              proc{&X::add}
        {}
    
        T add(T v) { return v + val; }
        T curproc(T v) { return (this->*proc)(v); }
    
        T val;
        valproc proc;
    };
    

    Live Demo

    时髦的语法(this-&gt;*proc)(i) 表示“使用参数i 在this 指向的对象上调用proc 指向的成员函数”。

    【讨论】:

      【解决方案2】:
      #include <stdio.h>
      
      template<typename T>
      class X {
      public:
          X(T v);
          T add(T v);
          T val;
          int (X::*curproc)(T v);
      };
      
      template<typename T>
      X<T>::X(T v) : val(v) {
          curproc = &X<T>::add;
      }
      
      template<typename T>
      T X<T>::add(T v) {
          return v+val;
      }
      
      int main()
      {
          printf("Hello World\n");
          X<int> *p = new X<int>(3);
      
          printf("%d\n",  (p->*(p->curproc))(7));
      }
      

      【讨论】:

        【解决方案3】:

        【讨论】:

        • 这是相关的,但没有解决成员函数指针的问题
        • 当我将类的整个代码放入头文件时,我得到相同的编译器错误
        【解决方案4】:

        改变

        return  p->curproc(7);
        

        到

        return (p->*(p->curproc))(7);
        

        *(p->currproc) 是函数指针,需要在 p 对象指针上调用

        详情

        C++ function pointer (class member) to non-static member function

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-10-16
          • 1970-01-01
          • 1970-01-01
          • 2015-04-26
          • 1970-01-01
          相关资源
          最近更新 更多