有人可以解释“参考”之间的区别。和“指针”在这种情况下? [英] Could someone please explain the difference between a "reference" and a "pointer" in this case?

查看:87
本文介绍了有人可以解释“参考”之间的区别。和“指针”在这种情况下?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我阅读 litb回答这个问题,我学到了通过引用传递数组允许我们获得它的大小。我只是打了一点代码,并试图通过引用传递一个函数,令人惊讶(至少对我来说),这段代码编译:

  void execute(void(& func)())// func通过引用传递! 
{
func();
}

最后一个函数和这个函数之间有什么区别:

  void execute(void(* func)())// func由指针传递! 
{
func();
}



我尝试使用VC2008,它在每种情况下产生不同的输出。奇怪的是编译器在函数指针的情况下更好地优化代码:

  void print()
{
std :: cout<< Hello References!;
}
void execute(void(& func)())// optimized
{
func
}
int main()
{
00291020 call print(291000h)
}
============= ==========================
//在这种情况下,编译器删除代码中的所有函数调用!
void print()// optimize!
{
std :: cout<< Hello Pointers!;
}
void execute(void(* func)())// optimized
{
func();
}
int main()
{
002F1005推送偏移字符串Hello References! (2F2124h)
002F100A push eax
002F100B调用std :: operator<<< std :: char_traits< char> > (2F1150h)
}

有一个区别,



注意:代码是使用VC2008编译的, / O2

EDIT ::
我真的对函数引用和函数指针之间的任何区别感兴趣。

解决方案

对于语言差异(仅保留函数声明,因为这只是重要的)

  void execute(void(& func) 

void g();
int main(){
void(* fp)()= g;
execute(fp); //不工作
execute(& g); //不工作
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 ; u(); } 

现在你可以初始化函数的引用和指针,当然不是函数本身。在第二个定义中, T 将通过模板参数推导被推导到函数指针类型,传递一个函数将隐式转换为该指针参数类型。所以一切都会好起来。






我不知道为什么MSVC对它们进行不同的内联处理 - 但我也怀疑这是因为函数引用。


When I read litb answer to this question, I learned that passing an array by reference allows us to obtain its size. I just played little bit with code, and tried to pass a "function" by reference and surprisingly (at least for me), this code compiles:

void execute( void (&func)() ) // func is passed by reference!
{
    func();
}

Is there any difference between the last function, and this one:

void execute( void (*func)() ) // func is passed by pointer!
{
    func();
}

I tried it using VC2008, and it produces different output in each case. The strange thing is that the compiler optimizes the code better in case of a function pointer:

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) 
}

There has to be a difference, although I don't see it, right?

Note: the code was compiled using VC2008, with /O2 and /Ot turned on.


EDIT:: I am really interested about any difference between function references and function pointers. I examined the produced assembly code just to see how it is translated in each case.

解决方案

For the language difference (keeping only the function declarations below, since that's what's important only)

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
}

It doesn't work, because it wants a function, not a function pointer. For the same reason that array answer rejects a pointer, this rejects a pointer too. You have to pass "g" directly.

For templates, it matters too

template<typename T>
void execute(T &t) { T u = t; u(); }

template<typename T>
void execute(T t) { T u = t; u(); }

Those two are very different from one another. If you call it with execute(g); like above, then the first will try to declare a function and initialize it with t (reference to g). The generated function would look like this

void execute(void(&t)()) { void u() = t; u(); }

Now you can initialize references and pointers to functions, but of course not functions itself. In the second definition, T will be deduced to a function pointer type by template argument deduction, and passing a function will convert it to that pointer parameter type implicitly. So everything will go fine.


I don't know why MSVC treats them differently for inlining - but i also suspect it's because function references appear more seldom.

这篇关于有人可以解释“参考”之间的区别。和“指针”在这种情况下?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆