The compiler really does not see the declaration of the function, if it is not declared outside the class, and there is no argument-dependent name lookup ( ADL - Argument-Dependent Name Lookup ).
Therefore, declare a friendly function also after defining the class.
class myClass { private: int i,j; public: myClass(); virtual ~myClass(); friend void myFunc(); }; void myFunc();
Compare these two demonstration programs.
#include <iostream> class myClass { private: int i,j; public: myClass(){} virtual ~myClass(){} friend void myFunc() { std::cout << "Hi, I'm friend!" << std::endl; } }; //void myFunc(); //^^^^^^^^^^^^^^ int main() { myFunc(); return 0; }
and
#include <iostream> class myClass { private: int i,j; public: myClass(){} virtual ~myClass(){} friend void myFunc() { std::cout << "Hi, I'm friend!" << std::endl; } }; void myFunc(); //^^^^^^^^^^^^ int main() { myFunc(); return 0; }
In the first case, a compilation error will occur, indicating that the name myFunc not declared. In the second case, the program will successfully compile and output the text to the console.
Hi, I'm friend!
In the first case, when the compiler encounters the name myFunc , it searches for it in the global namespace and does not find it. Therefore, it issues a diagnostic message similar to the one shown.
'myFunc'
If a friend function declared in a class had an argument that has a class type, the compiler could find this function using an argument-dependent name search (ADL). For example,
#include <iostream> class myClass { private: int i,j; public: myClass() : i( 10 ), j( 20 ){} virtual ~myClass(){} friend void myFunc( const myClass &c ) { std::cout << "Hi, I'm friend!" << std::endl; std::cout << "You have i = " << ci << " and j = " << cj << std::endl; } }; int main() { myClass c; myFunc( c ); return 0; }
This program is successfully compiled and displayed on the console.
Hi, I'm friend! You have i = 10 and j = 20
Since the friendly function has a parameter of type const myClass & , using the ADL, the compiler will look for the declaration of a friendly function also in the class myClass .
Name-dependent (ADL) dependent argument can be disabled by enclosing the function name in parentheses. Tvk, for example, the following program will not be compiled due to the fact that the function name is enclosed in parentheses, and ADL will not be applied to the search for the function name.
#include <iostream> class myClass { private: int i,j; public: myClass() : i( 10 ), j( 20 ){} virtual ~myClass(){} friend void myFunc( const myClass &c ) { std::cout << "Hi, I'm friend!" << std::endl; std::cout << "You have i = " << ci << " and j = " << cj << std::endl; } }; int main() { myClass c; ( myFunc )( c ); return 0; }
объявлениеlabel is strange in its meaning. - Visman