// -----------
// Friends.c++
// -----------
#include <cassert> // assert
#include <iostream> // cout, endl
// -
// f
// -
int f1 ();
template <typename T>
int f2 ();
template <typename T>
int f3 ();
template <typename T>
int f4 ();
// -
// B
// -
struct B1 {
int f ();};
template <typename T>
struct B2 {
int f ();};
template <typename T>
struct B3 {
int f ();};
template <typename T>
struct B4 {
int f ();};
// -
// C
// -
struct C1 {
int f ();};
template <typename T>
struct C2 {
int f ();};
template <typename T>
struct C3 {
int f ();};
template <typename T>
struct C4 {
int f ();};
// -
// A
// -
template <typename T>
class A {
// global function f1
friend int f1 ();
// 'int' instance of global function template f2
friend int f2<int>();
// T instance of global function template f3
friend int f3<T>();
// all instances of global function template f4
template <typename U>
friend int f4(); // not f4<U>()!
// struct B1
friend struct B1;
// 'int' instance of class template B2
friend struct B2<int>;
// T instance of class template B3
friend struct B3<T>;
// all instances of class template B4
template <typename U>
friend struct B4; // not B4<U>!
// class C1 method f
friend int C1::f();
// 'int' instance of class template C2 method f
friend int C2<int>::f();
// T instance of class template C3 method f
friend int C3<T>::f();
// all instances of class template C4 method f
template <typename U>
friend int C4<U>::f(); // not C4::f()!
private:
int i;
public:
A (int i) :
i (i)
{}};
// -
// f
// -
int f1 () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int f2 () {
A<double> x = 2;
return ++x.i;}
template <typename T>
int f3 () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int f4 () {
A<bool> x = 2;
return ++x.i;}
// -
// B
// -
int B1::f () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int B2<T>::f () {
A<double> x = 2;
return ++x.i;}
template <typename T>
int B3<T>::f () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int B4<T>::f () {
A<bool> x = 2;
return ++x.i;}
// -
// C
// -
int C1::f () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int C2<T>::f () {
A<double> x = 2;
return ++x.i;}
template <typename T>
int C3<T>::f () {
A<int> x = 2;
return ++x.i;}
template <typename T>
int C4<T>::f () {
A<bool> x = 2;
return ++x.i;}
// ----
// main
// ----
int main () {
using namespace std;
cout << "Friends.c++" << endl;
{
assert(f1() == 3); // f1 friend of A<int>
assert(f2<int>() == 3); // f2<int> friend of A<double>
// assert(f2<double>() == 3); // f2<int> friend of A<double>
assert(f3<int>() == 3); // f3<T> friend of A<int>
// assert(f3<double>() == 3); // f3<T> friend of A<int>
assert(f4<int>() == 3); // f4<U> friend of A<bool>
assert(f4<double>() == 3); // f4<U> friend of A<bool>
}
{
B1 x; // B1 friend of A<int>
assert(x.f() == 3);
}
{
B2<int> x; // B2<int> friend of A<double>
assert(x.f() == 3);
}
/*
{
B2<double> x; // B2<int> friend of A<double>
assert(x.f() == 3);
}
*/
{
B3<int> x; // B3<T> friend of A<int>
assert(x.f() == 3);
}
/*
{
B3<double> x; // B3<T> friend of A<int>
assert(x.f() == 3);
}
*/
{
B4<int> x; // B4<U> friend of A<bool>
assert(x.f() == 3);
}
{
B4<double> x; // B4<U> friend of A<bool>
assert(x.f() == 3);
}
{
C1 x; // C1 friend of A<int>
assert(x.f() == 3);
}
{
C2<int> x; // C2<int> friend of A<double>
assert(x.f() == 3);
}
/*
{
C2<double> x; // C2<int> friend of A<double>
assert(x.f() == 3);
}
*/
{
C3<int> x; // C3<T> friend of A<int>
assert(x.f() == 3);
}
/*
{
C3<double> x; // C3<T> friend of A<int>
assert(x.f() == 3);
}
*/
{
C4<int> x; // C4<U> friend of A<bool>
assert(x.f() == 3);
}
{
C4<double> x; // C4<U> friend of A<bool>
assert(x.f() == 3);
}
cout << "Done." << endl;
return 0;}
syntax highlighted by Code2HTML, v. 0.9.1