检查以下代码:
#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
函数(即使它不应该这样)?
答案 0 :(得分:6)
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*
比在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*