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

发布于 2024-12-29 19:54:50 字数 1606 浏览 1 评论 0原文

我对 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 是指针 -------- g 的 T 减去指针是 功能

(多次)解引用自由函数(!!!)g 的 T 是指针 -------- g 减去指针后的 T 就是函数

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

所以(请原谅我这个问题的开放性):为什么函数和函数指针的处理方式如此不同,也就是说,为什么前者被威胁为真正的指针,而后者?有历史原因吗?

I am puzzled by the way that C++ treats function pointers and member function pointers, so I distill my doubts in this example code:

#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);
}

This code prints:

free function T of g is pointer -------- T of g less a pointer is
function

(multiple times) dereferenced free function (!!!) T of g is pointer
-------- T of g less a pointer is function

member function T of g is member function pointer -------- T of g less
a pointer is member function pointer

So (forgive me once for the openness of the question): why functions and function pointers are treated so differently, that is, why the former are threated as true pointers whereas the latter? Are there historical reasons?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

定格我的天空 2025-01-05 19:54:50

如果函数是虚函数,则指向成员函数的指针必须正确工作。在这种情况下,它不能只是指向函数的指针,因为它必须根据其所应用的对象的动态类型分派到不同的函数。

它通常包含:

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

A pointer to member function has to work correctly if the function is virtual. In that case, it can't simply be a pointer to the function, since it must dispatch to a different function depending on the dynamic type of the object it's applied to.

It will typically contain:

  • A flag to indicate whether it's virtual;
  • If non-virtual, a "normal" function pointer;
  • If virtual, the index of the function in the vtable (assuming virtual dispatch is implemented with a table).
伪心 2025-01-05 19:54:50

从历史上看,C++ 源自 C,并试图兼容
共同特征。关于函数,C 有点含糊
关于函数本身和指针之间的区别
到函数:函数的名称转换为函数指针
除非它后面紧跟着一个“(”标记和一个指向
函数接受“(”运算符,就像函数一样。对于
兼容性原因,C++也是如此。

与 C 的兼容性对于成员函数不起作用,因此 C++
正确地使用它们:函数不是指向
函数,并且没有理由在它们之间进行隐式转换。

(从那时起,STL 就利用了这样一个事实:您可以
“调用”函数指针,这样就可以使用函数了
(或者更确切地说,指向函数的指针)作为可调用对象。)

Historically, C++ derived from C, and tries to be compatible in the
common features. With regards to functions, C is a bit ambiguous with
regards to the distinction between the functions themselves and pointers
to functions: the name of a function converts to a pointer to function
unless it is immediately followed by a '(' token, and a pointer to
function accepts the '(' operator, exactly like a function does. For
compatibility reasons, C++ does the same.

Compatibility with C doesn't come into play for member functions, so C++
does things correctly with them: a function is not a pointer to a
function, and there's no reason for an implicit conversion between them.

(Since then, STL has leveraged off the fact that you can
“call” a pointer to function, so that you can use functions
(or rather pointers to functions) as callable objects.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文