corrections
There is a hot fix, but read the explanation below if you want to understand what is going on.
#include <iostream> template<typename T> int ticket(); class Manager { public: template<typename T> friend int ticket() { return ++Manager::counter; } static int counter; }; int Manager::counter; // don't forget the definition int main() { Manager m; std::cout << "ticket: " << ticket<int>() << std::endl; }
As the snippet shows, you must declare a template so that it displays when you call it.
Friend Function Definitions
This is confusing, as there are some rules in this case. Some highlights, and then some other highlights.
struct A { friend void f(A*) { std::cout << "hello"; } };
What is he doing? It defines the function of a friend. Such a function is a member of the encompassing namespace. This is not a member of the class, although it is defined inside the class! The fact that it is defined in a class only changes the lexical domain of this function: it can directly refer to members of this class without preceding the class name.
Most importantly, however, the function is not visible after the announcement. You cannot make your address like this, for example
&f
The only way the function will work is to use an argument-dependent search. A search that ends with this class as an associated class will consider this friend function. This means that the following work:
f((A*)0);
This works because the call includes an argument with the type the class is included in. In this case, the class is an associated class, and a friend’s declaration will be considered.
The following actions will not work, for example
f(0);
Because he does not know that he must look for A to find a friend’s ad. The function of determining the function of a friend without an argument will not be found, because after that there is no search dependent on the argument.
Friend Function Definition for Templates
In addition to the fact that your call does not include arguments, it has another problem. If you define a friend function template, things are more complicated. There is a rule that says that if the compiler sees T<A1, A2, A3> , this only applies to the specialization of the template, if T actually resolves the template. Consider
ticket < int > ()
The compiler cannot resolve ticket because it does not appear in a normal search. Therefore, the rule states that ticket<int> not a function. It should be analyzed as a relational expression, which leads to the following
(ticket < int) > ()
This will be a syntax error because int not a value and () not a value.
Example
Here is an example where it matters.
struct A { template<int I> friend void f(A*) { } };
It compiles. It compiles because f resolves the pattern (although it is completely different, which cannot even accept a non-type pattern argument), but it does not matter!). But the standard compatible compiler will not compile the fragment as soon as you comment out the second declaration, because it is compiled as a relational expression (less and less), and it will not find the character f .
Read this topic for more information: What am I missing in this template game example? .