为什么指向函数的指针等于 1?
Why pointer to function is equal to 1?
检查以下代码:
#include <iostream>
using namespace std;
int& foo() {
static int i = 0;
return i;
}
int main() {
cout << &foo() << endl;
cout << &foo << endl;
return 0;
}
如您所见,第一个 cout
打印 return 的地址 foo()
的值,这将是 foo()
中的静态变量 i
。对于第二个 cout
,我期望 &foo
return 是 foo()
函数的地址,如 here:
所述
2) If the operand is a qualified name of a non-static member, e.g.
&C::member, the result is a prvalue pointer to member function or
pointer to data member of type T in class C. Note that neither &member
nor C::member nor even &(C::member) may be used to initialize a
pointer to member.
但令我惊讶的是,这是我的输出:
0x5650dc8dc174
1
第一个可以,但是第二个是1
?这是怎么发生的?为了确保我没有搞砸任何东西,我在 C
:
中写了这段代码
#include <stdio.h>
int foo() {
}
int main(void) {
printf("%p", &foo);
return 0;
}
具有以下输出:
0x55732bd426f0
按预期工作。我是否遗漏了 C++
代码中的某些内容?或者这可能是因为内联 foo
函数(即使它不应该是这样的)?
operator<<
没有匹配函数指针的重载。所以最佳匹配是 basic_ostream& operator<<(bool value)
.
还有一个 operator<<
重载为 basic_ostream& operator<<(const void * value)
。但是函数指针无法隐式转换为 const void*
.
如果您想打印一个函数的地址,您可以使用 reinterpret_cast
或 C 风格转换将其转换为 void *
。
std::basic_ostream::operator<<
有两个重载 bool
和 const void*
;注意没有重载函数指针。
basic_ostream& operator<<( bool value ); (6)
basic_ostream& operator<<( const void* value ); (7)
对于int*
和传递给std::basic_ostream::operator<<
的函数指针,这里都需要隐式转换。
传递int*
时,选择了(7)重载,因为隐式转换converting from int*
to const void*
is perferred than the one converting to bool
in overload resolution,
If two conversion sequences are indistinguishable because they have
the same rank, the following additional rules apply:
1) Conversion that involves pointer to bool, pointer-to-member to
bool, or std::nullptr_t to bool conversion is worse than the one that
doesn't
和
A prvalue pointer to any (optionally cv-qualified) object type T can be converted to a prvalue pointer to (identically cv-qualified) void. The resulting pointer represents the same location in memory as the original pointer value.
传递函数指针时,选择了(6)重载;函数指针可以是 converted to bool
implicitly,但不能指向 const void*
.
A prvalue of integral, floating-point, unscoped enumeration, pointer,
and pointer-to-member types can be converted to a prvalue of type
bool.
The value zero (for integral, floating-point, and unscoped
enumeration) and the null pointer and the null pointer-to-member
values become false. All other values become true.
你看到的是
std::ostream& operator<<( bool );
来自 cppreference:
There are no overload for pointers to non-static member, pointers to
volatile, or function pointers (other than the ones with
signatures accepted by the (10-12) overloads). Attempting to output
such objects invokes implicit conversion to bool, and, for any
non-null pointer value, the value 1 is printed (unless boolalpha was
set, in which case true is printed).
要查看可以转换为 void*
的指针值:
std::cout << (void*)foo;
检查以下代码:
#include <iostream>
using namespace std;
int& foo() {
static int i = 0;
return i;
}
int main() {
cout << &foo() << endl;
cout << &foo << endl;
return 0;
}
如您所见,第一个 cout
打印 return 的地址 foo()
的值,这将是 foo()
中的静态变量 i
。对于第二个 cout
,我期望 &foo
return 是 foo()
函数的地址,如 here:
2) If the operand is a qualified name of a non-static member, e.g. &C::member, the result is a prvalue pointer to member function or pointer to data member of type T in class C. Note that neither &member nor C::member nor even &(C::member) may be used to initialize a pointer to member.
但令我惊讶的是,这是我的输出:
0x5650dc8dc174
1
第一个可以,但是第二个是1
?这是怎么发生的?为了确保我没有搞砸任何东西,我在 C
:
#include <stdio.h>
int foo() {
}
int main(void) {
printf("%p", &foo);
return 0;
}
具有以下输出:
0x55732bd426f0
按预期工作。我是否遗漏了 C++
代码中的某些内容?或者这可能是因为内联 foo
函数(即使它不应该是这样的)?
operator<<
没有匹配函数指针的重载。所以最佳匹配是 basic_ostream& operator<<(bool value)
.
还有一个 operator<<
重载为 basic_ostream& operator<<(const void * value)
。但是函数指针无法隐式转换为 const void*
.
如果您想打印一个函数的地址,您可以使用 reinterpret_cast
或 C 风格转换将其转换为 void *
。
std::basic_ostream::operator<<
有两个重载 bool
和 const void*
;注意没有重载函数指针。
basic_ostream& operator<<( bool value ); (6) basic_ostream& operator<<( const void* value ); (7)
对于int*
和传递给std::basic_ostream::operator<<
的函数指针,这里都需要隐式转换。
传递int*
时,选择了(7)重载,因为隐式转换converting from int*
to const void*
is perferred than the one converting to bool
in overload resolution,
If two conversion sequences are indistinguishable because they have the same rank, the following additional rules apply:
1) Conversion that involves pointer to bool, pointer-to-member to bool, or std::nullptr_t to bool conversion is worse than the one that doesn't
和
A prvalue pointer to any (optionally cv-qualified) object type T can be converted to a prvalue pointer to (identically cv-qualified) void. The resulting pointer represents the same location in memory as the original pointer value.
传递函数指针时,选择了(6)重载;函数指针可以是 converted to bool
implicitly,但不能指向 const void*
.
A prvalue of integral, floating-point, unscoped enumeration, pointer, and pointer-to-member types can be converted to a prvalue of type bool.
The value zero (for integral, floating-point, and unscoped enumeration) and the null pointer and the null pointer-to-member values become false. All other values become true.
你看到的是
std::ostream& operator<<( bool );
来自 cppreference:
There are no overload for pointers to non-static member, pointers to volatile, or function pointers (other than the ones with signatures accepted by the (10-12) overloads). Attempting to output such objects invokes implicit conversion to bool, and, for any non-null pointer value, the value 1 is printed (unless boolalpha was set, in which case true is printed).
要查看可以转换为 void*
的指针值:
std::cout << (void*)foo;