当我阅读litb answer to this question时,我了解到通过引用传递数组可以让我们获得它的大小。我只是玩了一点代码,试图通过引用传递一个“函数”,并且令人惊讶地(至少对我而言),这段代码编译:
void execute( void (&func)() ) // func is passed by reference!
{
func();
}
最后一个函数与此函数之间是否有任何区别:
void execute( void (*func)() ) // func is passed by pointer!
{
func();
}
我尝试使用VC2008,它会在每种情况下产生不同的输出。奇怪的是,在函数指针的情况下,编译器会更好地优化代码:
void print()
{
std::cout << "Hello References!";
}
void execute( void (&func)() ) // optimized
{
func();
}
int main()
{
00291020 call print (291000h)
}
=========================================
// In this case, the compiler removes all function calls in the code!
void print() // optimized!
{
std::cout << "Hello Pointers!";
}
void execute( void (*func)() ) // optimized
{
func();
}
int main()
{
002F1005 push offset string "Hello References!" (2F2124h)
002F100A push eax
002F100B call std::operator<<<std::char_traits<char> > (2F1150h)
}
必须有区别,虽然我没有看到,对吗?
注意:代码是使用VC2008编译的,/O2
和/Ot
已打开。
编辑:: 我真的对函数引用和函数指针之间的区别感兴趣。我检查了生成的汇编代码,看看它是如何在每种情况下进行翻译的。
答案 0 :(得分:3)
这并不常见,因此可能只是VS团队没有添加规则来优化它。
答案 1 :(得分:3)
我认为这是由于C ++标准4.3:
函数类型T的左值可以转换为“指向T的指针”的右值。结果是指向 功能。
答案 2 :(得分:3)
对于语言差异(仅保留下面的函数声明,因为这只是重要的)
void execute( void (&func)() );
void g();
int main() {
void (*fp)() = g;
execute(fp); // doesn't work
execute(&g); // doesn't work either
execute(g); // works
}
它不起作用,因为它需要一个函数,而不是一个函数指针。出于同样的原因,数组答案拒绝指针,这也拒绝指针。你必须直接传递“g”。
对于模板,它也很重要
template<typename T>
void execute(T &t) { T u = t; u(); }
template<typename T>
void execute(T t) { T u = t; u(); }
这两者彼此非常不同。如果您使用上面的execute(g);
调用它,那么第一个将尝试声明一个函数并使用t
初始化它(引用g
)。生成的函数看起来像这样
void execute(void(&t)()) { void u() = t; u(); }
现在您可以初始化函数的引用和指针,但当然不是函数本身。在第二个定义中,T
将通过模板参数推导推导为函数指针类型,并且传递函数将隐式地将其转换为该指针参数类型。所以一切都会好起来的。
我不知道为什么MSVC会以不同的方式对待内联 - 但我也怀疑它是因为函数引用似乎更少见。
答案 3 :(得分:-2)
引用(&amp;)和指针(*)之间的区别在于引用提供变量的地址或位置,指针指向存储在其中的地址的内存中的位置。
int *pointer;
int variable;
pointer = &variable; // assigning the address of variable to pointer
variable = 53; // value of variable
cout << *pointer; // This should output the value of the address where is pointing, in this
// case 53, that is the value of variable to where is pointing.
我们可以得出结论,(&amp;变量)具有该内存位置的地址,* anyname指向存储在其内存中的地址......