2011-09-06 12 views
7

Jaka jest różnica międzyodwołanie do funkcji składni - zi bez &

typedef void (&FunctionTypeR)(); 

vs

typedef void (FunctionType)(); 

to drugi też odniesienie do funkcji? Czy FunctionTypeR jest odpowiednikiem FunctionType&, gdy jest używany jako typ argumentu?

Dla

void foo(FunctionType bar) 

Czy środowisko wykonawcze tworzy kopię pasku argument (funkcji), gdy foo jest wywoływana?

Odpowiedz

12

Różnica polega na tym, że nie mogą tworzyć obiekty typu funkcji, ale można tworzyć obiektów funkcji wskaźnik rodzaj i funkcję odniesienia typu.

Oznacza to, że jeśli masz funkcję, powiedzmy f() jak:

void f(){} 

to tutaj jest to, co można zrobić, a czego nie może zrobić: kod

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

test:

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

Zobacz teraz błąd kompilacji (i ostrzeżenia):

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’ 

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


Jednak jeśli używasz FunctionType (która jest rodzajem funkcji) w liście parametrów funkcji jak:

void foo(FunctionType bar); 

to jest to równoznaczne z

void foo(FunctionType * bar); 

Oznacza to, że O znaczenia, co piszesz, można wywołać funkcję używając bar jak:

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

Oznacza to, że można napisać tak:

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

Demo: http://ideone.com/kwUE9

Wynika to funkcji typ do regulacji wskaźnika typu regulacja; czyli rodzaj funkcja jest regulować stać się wskaźnik funkcjonować typ:

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

C++ 03 Standardowe mówi w §13.1/3, zgłoszeń

parametrów, które różnią się tylko tym, że jeden jest funkcją typu i drugi wskaźnik tego samego typu reakcji są równoważną. To znaczy, że typ funkcji jest dostosowywany, aby stać się wskaźnikiem dla typu funkcji (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()) 
] 

A jeśli używasz `FunctionTypeR (która jest funkcją odniesienia typ) jako:

void foo(FunctionTypeR bar); 

to jest to równoznaczne z:

void foo(FunctionType * & bar); 

, a

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

Demo: http://ideone.com/SmtQv


interesująca część ...

Można użyć FunctionType do zadeklarować funkcji (ale nie go zdefiniować).

Na przykład

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

+0

Czy to znaczy void foo (bar FunctionType) jest rzeczywiście foo (FunctionType & bar)? która jest odpowiednikiem foo (FunctionTypeR bar)? –

+0

Nie, to błąd. – Shahbaz

+0

void 'foo (FunctionType bar)' nie jest błędem. kompiluje i działa. Błąd to "FunctionType fun1 = f"; –

Powiązane problemy