为什么自由函数指针总是类型指针,而成员函数指针实际上不是指针?

时间:2012-01-30 15:53:43

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

我对C ++处理函数指针和成员函数指针的方式感到困惑,所以我在这个示例代码中提炼了我的怀疑:

#include <iostream>
#include <type_traits>
#include <functional>
#include <typeinfo>
using namespace std;

struct asd{ void f(){ } };
void f(){}

template<typename T> void g(T f){
    cout<<"T of g is "<<
            (is_pointer<T>::value?"pointer":
                    (is_function<T>::value?"function":
                            (is_member_function_pointer<T>::value?"member function pointer":
                                    "something else")))<<" -------- ";

    typedef typename remove_pointer<T>::type TlessPointer;
    cout<<"T of g less a pointer is "<<
            (is_pointer<TlessPointer>::value?"pointer":
                    (is_function<TlessPointer>::value?"function":
                            (is_member_function_pointer<TlessPointer>::value?"member function pointer":
                                    "something else")))<<endl;
}

int main(){
    cout<<"free function ";
    g(f);
    cout<<endl<<"(multiple times) dereferenced free function (!!!) ";
    g(******f);
    cout<<endl<<"member function ";
    g(&asd::f);
    //this won't compile: g(*&asd::f);
}

此代码打印:

  

g的自由函数T是指针--------少了一个指针的T是   功能

     

(多次)解除引用的自由函数(!!!)g的t是指针   --------少了一个指针就是函数

     

成员函数T是成员函数指针-------- T of g less   指针是成员函数指针

所以(请原谅我一次的问题的开放性):为什么函数和函数指针被如此区别对待,也就是说,为什么前者被威胁为真正的指针而后者呢?有历史原因吗?

2 个答案:

答案 0 :(得分:6)

如果函数是虚函数,则指向成员函数的指针必须正常工作。在这种情况下,它不能简单地是一个指向函数的指针,因为它必须根据它所应用的对象的动态类型调度到不同的函数。

通常包含:

  • 一个标志,指示它是否为虚拟;
  • 如果是非虚拟的,则为“普通”函数指针;
  • 如果是虚拟,则表示vtable中的函数索引(假设虚拟调度是使用表实现的)。

答案 1 :(得分:4)

历史上,C ++派生自C,并尝试兼容 共同特征。关于功能,C有点含糊不清 关于函数本身和指针之间的区别 to functions:函数名称转换为指向函数的指针 除非它后面紧跟一个'('标记和一个指向 函数接受'('运算符,就像函数一样。对于 兼容性原因,C ++也是如此。

与C的兼容性不适用于成员函数,因此C ++ 用它们做正确的事情:函数不是指向a的指针 函数,没有理由在它们之间进行隐式转换。

(从那以后,STL利用了你可以做到的事实 “调用”指向函数的指针,以便您可以使用函数 (或者指向函数的指针)作为可调用对象。)