1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
| #include <iostream>
class A;
template<typename T> void f1(A& a, T v);
template<typename T> void f1_1(A& a, T v);
template<typename T> void f3(A& a, T v);
void f2(A& a, int v);
class A
{
int a;
friend void ::f1<>(A&, int); // первое правило - привязывает к шаблонам
friend void f1_1<>(A&, int); // также первое правило - привязывает к шаблонам, т.е квалификация не обязательна.
friend void ::f2(A&, int); // второе правило - привязывает к обычным функциям
friend void ::f3(A&, int); // третье правило - если (2)-ой вариант не сработал - обязаны попытаться привязать к шаблону. Юзая классическую дедукцию аргументов шаблона.
friend void f4(A&, int); // четвертое правило - компилятор сам объявит эту функцию.
};
template<>
void f1<int>(A& a, int v)
{
a.a = v;
std::cout << a.a;
}
template<>
void f1_1<int>(A& a, int v)
{
a.a = v;
std::cout << a.a;
}
void f2(A& a, int v)
{
a.a = v;
std::cout << a.a;
}
template<>
void f3<int>(A& a, int v)
{
a.a = v;
std::cout << a.a;
}
void f4(A& a, int v)
{
a.a = v;
std::cout << a.a;
}
int main()
{
A a;
f1(a,10);
f1_1(a,11);
f2(a,12);
f3(a,13);
f4(a,14);
} |