且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-12-27 09:31:43

不同之处在于不能创建函数类型的对象,但是可以创建函数指针类型。



这意味着如果你有一个函数,说 f () as:

  void f(){} 

那么这里是你能做什么,你不能做什么:

  FunctionType fun1 = f; //错误 - 无法创建函数类型的对象
FunctionType * fun2 = f; // ok
FunctionTypeR fun3 = f; // ok

测试代码:

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

void f(){}

int main(){
FunctionType fun1 = f; //错误 - 无法创建函数类型的对象
FunctionType * fun2 = f; // ok
FunctionTypeR fun3 = f; // ok
return 0;
}



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

  prog.cpp:在函数'int main()':
prog.cpp:7:error:function'void fun1被初始化为一个变量
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 as:

  bar // ok 
(* bar)(); // ok

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

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

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



这是因为函数类型为函数指针类型调整;

$ pre> 函数类型|函数指针类型(调整类型)
void()| void(*)()
void(int)| void(*)(int)
int(int,int)| int(*)(int,int)
.... | ...等等。

C ++ 03标准在§13.1/ >


参数声明的区别仅在于一个是函数类型,另一个是指向相同函数类型的指针等效也就是说,函数类型会调整为指向函数类型(8.3.5)的指针。




  [示例:
void h(int());
void h(int(*)()); //重定义h(int())
void h(int x()){} // h(int())的定义
void h(int(* x)()){ } //形式不正确:redefinition of h(int())
]

如果您使用`FunctionTypeR (这是一个函数引用类型):

  void foo(FunctionTypeR bar); 

那么它等效于:

  void foo(FunctionType *& bar); 

并且,

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

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






有趣的部分...



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



p>

  struct A 
{
//成员函数声明。
FunctionType f; //等价于:void f();
};

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

//转发声明
FunctionType h; //等价于:void h();

int main(){
A a;
a.f(); //调用成员函数
h(); //调用非成员函数
}

void h()//定义在main()之下
{
std :: cout< hmmm ..< std :: endl;
}

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


What's the difference between

typedef void (&FunctionTypeR)();

vs

typedef void (FunctionType)();

Is the second also a reference to function? Is FunctionTypeR equivalent to FunctionType& when used as the type of an argument?

For

void foo(FunctionType bar)

Does the runtime makes a copy of the argument bar (a function) when foo is invoked?

The difference is that you cannot create objects of function type, but you can create of objects of function pointer type, and function reference type.

That means if you've a function, say f() as:

 void f(){}

then here is what you can do, and what you cannot do:

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

Test code:

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

Now see the compilation error (and warnings):

 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’

Online demo : http://ideone.com/hpTEv


However, if you use FunctionType (which is a function type) in a function parameter list as:

void foo(FunctionType bar);

then it's equivalent to

void foo(FunctionType * bar);

That means, no matter what you write, you can call the function using bar as:

   bar();  //ok
 (*bar)(); //ok 

That is, you can write this:

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

Demo : http://ideone.com/kwUE9

This is due to function type to function pointer type adjustment; that is, the function type is adjusted to become a pointer to function type:

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

The C++03 Standard says in §13.1/3,

Parameter declarations that differ only in that one is a function type and the other is a pointer to the same function type are equivalent. That is, the function type is adjusted to become a pointer to function type (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())
]

And if you use `FunctionTypeR (which is a function reference type) as:

void foo(FunctionTypeR bar);

then it's equivalent to:

void foo(FunctionType * & bar);

And,

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

Demo : http://ideone.com/SmtQv


Interesting part...

You can use FunctionType to declare a function (but not to define it).

For example,

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

Demo : http://ideone.com/W4ED2