为什么自由函数指针总是指针类型,而成员函数指针实际上不是指针?
我对 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 functionmember 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果函数是虚函数,则指向成员函数的指针必须正确工作。在这种情况下,它不能只是指向函数的指针,因为它必须根据其所应用的对象的动态类型分派到不同的函数。
它通常包含:
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:
从历史上看,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.)