How to hide a binding from everyone except class T

I need type A, which will lead to its hidden binding to an object of type T, but will hide the binding from everyone else. My C ++ compiler is GCC 4.4, but that doesn't matter. Why won't it work?

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    friend class T;
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return a.n1; }
    B() {}
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}

By the way, this works fine, except that it cannot hide the binding:

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    int n() const { return n1; }
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return a.n(); }
    B() {}
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}

Does C ++ really not allow you to specify a friend class at compile time as a template parameter? Why not? If not, what alternative technique should I use to hide the binding? (Prefer, if possible, a compile-time method.)

What is my misunderstanding, please?

( , , . , , . - , T , , , .)

.

+5
2

(. Xeo), ++ 03. , T , - T :

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    friend int T::getN1(const A& a) const;
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return getN1(a); }
    B() {}
  private:
    int getN1(const A<B>& a) const {return a.n1;}
};

class C {
  public:
    int f(const A<B> a) const { return getN1(a); }
    C() {}
  private:
    // Error, n1 is a private member of A<B>
    int getN1(const A<B>& a) const {return a.n1;}
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}

/ T A. , A, .

#include <iostream>

template <class T> class A {
  private:
    int n1;
  public:
    friend class T::AccessToA;
    A(const int n0 = 0) : n1(n0) {}
};

class B {
  public:
    int f(const A<B> a) const { return AccessToA::getN1(a); }
    B() {};
  private:
    friend class A<B>;
    struct AccessToA
    {
        static int getN1(const A<B>& a) {return a.n1;}
    };
};

class C {
  public:
    int f(const A<B> a) const { return AccessToA::getN1(a); }
    C() {};

  private:
    friend class A<C>;
    struct AccessToA
    {
        // Error, n1 is a private member of A<B>
        static int getN1(const A<B>& a) {return a.n1;}
    };
};

int main() {
    const A<B> a(5);
    const B b;
    const int m = b.f(a);
    std::cout << m << "\n";
    return 0;
}
+1

. ++ 11 .

§11.3 [class.friend] p3

, , :

  • friend elaborated-type-specifier ;
  • friend simple-type-specifier ;
  • friend typename-specifier ;

friend (, cv-qualit), friend; .

:

class C;
// [...]
template <typename T> class R {
  friend T;
};

R<C> rc;   // class C is a friend of R<C>
R<int> ri; // OK: "friend int;" is ignored

++ 03, , , "" -, . .

+4

All Articles