参考函数语法 - 有和没有&

时间:2011-09-06 15:01:31

标签: c++

之间有什么区别
typedef void (&FunctionTypeR)();

VS

typedef void (FunctionType)();

第二个也是函数的引用吗?当用作参数类型时,FunctionTypeR是否等同于FunctionType&

有关

void foo(FunctionType bar)

运行时是否在调用foo时复制参数栏(函数)?

1 个答案:

答案 0 :(得分:13)

区别在于你不能创建函数类型的对象,但你可以创建函数 pointer 类型的对象,并且函数 reference 类型。

这意味着如果你有一个功能,请说f()为:

 void f(){}

然后,这是你可以做的,你不能做的:

FunctionType  fun1 = f; //error - cannot create object of function type
FunctionType *fun2 = f; //ok 
FunctionTypeR fun3 = f; //ok

测试代码:

typedef void (&FunctionTypeR)();
typedef void FunctionType();

void f(){}

int main() {
        FunctionType  fun1 = f; //error - cannot create object of function type
        FunctionType *fun2 = f; //ok 
        FunctionTypeR fun3 = f; //ok
        return 0;
}

现在看到编译错误(和警告):

 prog.cpp: In function ‘int main()’:
 prog.cpp:7: error: function ‘void fun1()’ is initialized like a variable
 prog.cpp:8: warning: unused variable ‘fun2’
 prog.cpp:9: warning: unused variable ‘fun3’

在线演示:http://ideone.com/hpTEv


但是,如果在函数参数列表中使用FunctionType(函数类型):

void foo(FunctionType bar);

然后它相当于

void foo(FunctionType * bar);

这意味着,无论你写什么,你都可以使用bar作为:

来调用该函数
   bar();  //ok
 (*bar)(); //ok 

也就是说,你可以这样写:

void h(FunctionType fun) { fun(); }
void g(FunctionType fun) { (*fun)(); }

演示:http://ideone.com/kwUE9

这是由于函数类型到函数指针类型调整;也就是说,函数类型调整成为指向函数类型的指针

Function type     |  Function pointer type (adjusted type)
   void ()        |     void (*)()
   void (int)     |     void (*)(int)
   int  (int,int) |     int  (*)(int,int)
   ....           |      ... so on

C ++ 03标准在§13.1/ 3中说明,

  

参数声明只有一个是函数类型而另一个是指向同一函数类型的指针是等效即,调整函数类型以成为函数类型的指针(8.3.5)

[Example:
    void h(int());
    void h(int (*)()); // redeclaration of h(int())
    void h(int x()) { } // definition of h(int())
    void h(int (*x)()) { } // ill-formed: redefinition of h(int())
]

如果您使用`FunctionTypeR(函数引用类型):

void foo(FunctionTypeR bar);

然后它相当于:

void foo(FunctionType * & bar);

void h(FunctionTypeR fun) { fun(); }
void g(FunctionTypeR fun) { (*fun)(); }

演示:http://ideone.com/SmtQv


有趣的部分......

您可以使用FunctionType 声明一个函数(但不能定义它)。

例如,

struct A
{
   //member function declaration. 
    FunctionType f; //equivalent to : void f();
};

void A::f() //definition
{
  std::cout << "haha" << std::endl;
}

//forward declaration
FunctionType h; //equivalent to : void h();

int main() {
        A a;
        a.f(); //call member function
        h();   //call non-member function
}

void h() //definition goes below main()
{
   std::cout <<"hmmm.." << std::endl;
}

演示:http://ideone.com/W4ED2