1

I'm trying to declare a class template as a friend of another class template, so the private members in one class can be accessed by the other. For example I have two classes as the following:

A.h
template <typename T>
class A {
    private:
       T content;
}

and

B.h
#include "A.h"
template <typename T>
class B {
    public:
        void add(T);

    private:
        A<T>* ptr;
}

Now, I want to make class B< T> a friend of class A< T>, so I can have access to class A< T>'s content through class B< T>'s function add. So, I added a few lines to A.h:

A.h
template <typename T> class B;
template <typename T> 
class A {
    friend class B<T>;
    ...

I'm using Visual Studio and the above code would give me "unresolved external symbol..." error (Error code LNK2019). I have tried other variations but I kept getting a linker error. Please help me out. Thank you.

The definitions for the function add(T) is in B.cpp which I didn't write in the post.

HelperKing
  • 45
  • 1
  • 7
  • If you get a linker error, then compilation has succeeded, and your `friend` declaration works properly. This is a red herring. – Quentin Sep 30 '16 at 13:58
  • I'm sorry I wasn't aware those two were different. – HelperKing Sep 30 '16 at 14:04
  • 1
    Where is the definition (implementation) of `B::add()`? If you don't have one in the link, that will explain the linker error. – Peter Sep 30 '16 at 14:10

1 Answers1

1

The following code builds fine on gcc. I added a definition of B<T>::add(T), as it was missing. It's very possible that the absence caused your link - not compilation! - error.

template<typename T>
class B;

template <typename T>
class A {
    private:
       T content;

    friend B<T>;
};

template <typename T>
class B {
    public:
        void add(T t) { A<T> a; a.content = t; }

    private:
        A<T>* ptr;
};

int main() {
    A<int> a;
    B<int> b;
    b.add(3);
}
Ami Tavory
  • 74,578
  • 11
  • 141
  • 185
  • I just tested too and your code works fine when it's in one single file. However, what I want to do is implement a separate header file for each class. Would you please show me how it can be done? Thank you. – HelperKing Sep 30 '16 at 14:13
  • 1
    Since it's template code, then, in general, if the declaration is in a header file, then so should be the implementation (don't put parts of template code in a `.cpp` file). Is that your question? – Ami Tavory Sep 30 '16 at 14:15
  • That hit the spot right on. When I just put everything in the header file, it compiled perfectly. My poor understanding of these file types was the reason. Thank you so much. Could you also explain briefly why putting the implementations of functions in a separate .cpp file won't work? – HelperKing Sep 30 '16 at 14:21
  • 1
    @RuntimeError See [this question](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Ami Tavory Sep 30 '16 at 14:24