为什么指向函数的指针等于1?

时间:2018-11-03 07:40:06

标签: c++ function-pointers implicit-conversion

检查以下代码:

#include <iostream>
using namespace std;

int& foo() {
    static int i = 0;
    return i;
}

int main() {
    cout << &foo() << endl;
    cout << &foo << endl;

    return 0;
}

如您所见,第一个cout打印返回值foo()的地址,该返回值将是i中的静态变量foo()。对于第二个cout,我期望&foo返回foo()函数的地址,如here所述:

  

2)如果操作数是非静态成员的限定名称,例如   &C :: member,结果是指向成员函数的prvalue指针,或者   指向类C中类型T的数据成员的指针。请注意,&member都不   C :: member甚至&(C :: member)都不能用于初始化   指向成员的指针。

但令我惊讶的是,这是我的输出:

0x5650dc8dc174
1

第一个可以,但是第二个可以1?这是怎么发生的?为了确保没有弄乱任何内容,我在C中编写了以下代码:

#include <stdio.h>

int foo() {
}

int main(void) {
    printf("%p", &foo);
    return 0;
}

具有以下输出:

0x55732bd426f0

可正常使用。我是否错过了C++代码中的某些内容?还是因为内联foo函数(即使它不应该这样)?

3 个答案:

答案 0 :(得分:6)

std::basic_ostream::operator<<有两个重载,分别为boolconst 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*比在overload resolution中转换为bool的转换要容易,

  

如果两个转换序列无法区分,因为它们具有   等级相同,则适用以下附加规则:

     

1)转换涉及到bool的指针,指向成员的指针   bool或std :: nullptr_t转换为bool的效果比   不

  

指向任何(可选具有cv资格的)对象类型T的prvalue指针可以转换为指向(完全具有cv资格的)void的prvalue指针。结果指针与原始指针值在内存中的位置相同。

传递函数指针时,选择了(6)重载;函数指针可以为converted to bool implicitly,但不能为const void*

  

整数,浮点数,无作用域枚举,指针,   指针类型和成员类型可以转换为类型的prvalue   布尔。

     

零值(对于整数,浮点数和无作用域   枚举),空指针和指向成员的空指针   值变为假。所有其他值都变为true。

答案 1 :(得分:1)

operator<<没有与函数指针匹配的重载。因此,最佳匹配是basic_ostream& operator<<(bool value)

operator<<basic_ostream& operator<<(const void * value)还有另一个重载。但是函数指针不能隐式转换为const void*

如果要打印函数的地址,可以使用void *或C样式强制转换将其强制转换为reinterpret_cast

答案 2 :(得分:1)

您看到的是

public class CucumberSteps extends SpringTest {

@Autowired
private Mockedbean mockedbean;

@Autowired
private TestBean testBean;

来自cppreference

  

指向非静态成员的指针没有指向的重载。   易失性或功能指针(带有   (10-12)重载接受的签名)。尝试输出   这样的对象调用隐式转换为bool,并且对于任何对象   非null指针值,则将打印值1(除非boolalpha为   设置,在这种情况下将显示true)。

要查看指针值,可以将其强制转换为std::ostream& operator<<( bool );

void*