所以我只是使用函数指针,我记得你可以这样做:
void Foo() { } int main() { void(& func)() = Foo; func(); //::Foo(); }
明显的优点是引用引用有效对象(除非它们被误用),或者在这种情况下是函数.
明显的缺点是你不能存储一个引用数组,并且不能将它们用于成员函数指针(至少就我所知).
我的问题:有没有人使用它们(即函数引用,而不是函数指针),如果是这样,在什么情况下你发现它们有用/有用?
在使用条件编译时,唯一可以看到它们有用的地方是绑定对某个函数的引用.
我之前使用它们通过以类似策略模式的方式将它们传递给构造函数来向类添加自定义
我认为您的示例用法非常好.因为如果您使用普通函数指针,然后应用address-of运算符,您将获得函数指针的地址.使用对函数的引用将执行预期的操作,因为它返回指向函数本身的指针.
我也想不出很多例子.正如您所指出的,保持函数引用会产生一些难看的后果.另一个可能不需要的后果是,如果你作为一个类成员保存,如果你不编写自己的operator =你的对象将是不可赋值的,并且不要试图重新分配函数引用.
我认为函数引用的大多数用法都是隐式的,就像数组引用的大多数用法一样 - 尽管更多的是,当你通过引用接受参数时:
templatevoid do_something(T const& t) { ... }
虽然通过引用接受数组具有不丢失其大小信息的优点,但通过引用明确地接受函数似乎没有优势(至少就我所见).我认为函数引用的存在在很大程度上是通过引用的理想主义视图作为某个对象或函数的别名来证明的,同时它允许将函数传递给通过引用接受其参数的模板.
如果我不可能不需要它们,我可能会避免使用它们.常量函数指针还提供不可重新分配的可调用函数,当其他可能不熟悉这种语言的程序员读取您的代码时,它可能会避免混淆.值得注意的是,Vandervoorde和Josuttis也建议避免它们以减少混淆(在他们的书C++模板 - 完整指南中).
与函数指针不同,函数引用使得从无效源创建它们变得更加困难.如果要围绕C库创建一个包装器,这很有用 - C++代码可以通过引用获取回调函数,并且如果lbrary要求传递的指针不能为NULL,则将指针传递给C库.
它也是一种替代函数的便捷方法,特别是在带有新auto关键字的C++ 11中:
#include#include void f(int i, char c) { std::cout << i << ' ' << c << std::endl; } int main() { std::cout << typeid(f).name() << std::endl; //FvicE f(0, '1'); void (*pf)(int, char) (&f); //ugly std::cout << typeid(pf).name() << std::endl; //PFvicE (*pf)(2, '3'); pf(4, '5'); //works, but I don't recommend it void (&rf)(int, char) (f); //still ugly std::cout << typeid(rf).name() << std::endl; //FvicE rf(6, '7'); auto &af (f); //pretty, but only works in C++11 std::cout << typeid(af).name() << std::endl; //FvicE, same as above af(8, '9'); }