0
template <typename T>
class linked;

template <typename T>
class node {
    ...
    friend class linked<T>; 
};

template <typename T>
class linked {
    ...
};

Note that I have forward declared the linked class so as to declare it a friendly class of node but now I want to make a different .h and .cpp file for each of the class. How will I do the forward declaration in them.

Ram Sharma
  • 59
  • 1
  • 2
  • 10
  • 3
    There's no point in making .cpp files for these template classes. [Templates are *required* to be implemented in a header](https://stackoverflow.com/q/495021/501250) (unless you explicitly instantiate every instantiation you need, which is rarely a good idea) because the stuff that uses them needs to know the definition of the template class members in order to instantiate them. – cdhowie Sep 06 '17 at 14:11
  • If I were you I would just declare `node` as a struct and make all of it's members public. You really don't need access control as it is just a convenience object. – NathanOliver Sep 06 '17 at 14:14
  • @cdhowie I have a diferent code this is the simpified version of that and there it is required of me to make different cpp files for each and every class. how to implement forward declaration or anything similar in it – Ram Sharma Sep 06 '17 at 14:16
  • 1
    @RamSharma It's required of you to do something that *won't work?* – cdhowie Sep 06 '17 at 14:20
  • 2
    You forward declare as you already do. You need a forward declaration here, otherwise you get a circular include error. That said, `node` should be a member struct of linked, since they are tightly coupled. – sp2danny Sep 06 '17 at 14:20
  • 1
    A bit of terminology confusion here. `node` is _not_ a class. It's a template. To be exact, it's a class template. It it not a "template class". And the rule is that templates (class templates and function templates alike) go in header files. A rule about class definitions does not apply to things that aren't classes. – MSalters Sep 06 '17 at 14:51

2 Answers2

1

node.hpp

#pragma once

template <typename T> class linked; 
template <typename T> class node { 
... 
friend class linked<T>; 
};

linked.hpp

#pragma once
#include "node.hpp" // just because I guess you will use it in linked implementation
template <typename T> class linked { 
... 
};

So you can keep use node without linked.hpp included. You can even keep it private header and doesn't ship to user. But if linked some code wants to use linked class just include linked.hpp.

EDIT As an option node.hpp

#pragma once

template <typename T> class node { 
... 
class linked; 
friend class linked<T>; 
};

linked.hpp

#pragma once
#include "node.hpp"
template <typename T> class node<T>::linked { 
... 
};
0

You should consider having the whole declaration of the templates in .h files.

If you need to separate them you could:

linked.h:

template <typename T>
class linked;
#include "linked_implementation.tpp"

linked_implementation.tpp:

#ifndef LINKED_IMPLEMENTATION_TPP
#define LINKED_IMPLEMENTATION_TPP

template <typename T>
class node {
    ...
    friend class linked<T>; 
};

template <typename T>
class linked {
    ...
};

#endif

EDITED according to comments

Roberto
  • 2,115
  • 24
  • 32
  • You should also state they need to make sure `linked_implementation.cpp` is not add to the project as a file to be compiled. – NathanOliver Sep 06 '17 at 14:30
  • @NathanOliver is there a downside to compiling `linked_implementation.cpp` besides doing unnecessary work? – Kevin Sep 06 '17 at 14:35
  • I would avoid using the `cpp` extension entirely due to the reason that @NathanOliver mentioned. Some IDEs automatically build all `cpp` files, which would break in this case. Most people use `tpp` or `hpp` for class template implementations. – 0x5453 Sep 06 '17 at 14:35
  • @NathanOliver I think, correct me if I'm wrong, that it will compile just fine if the linked_implementation.cpp is added to the project, it would be "just" an overhead in the compilation process – Roberto Sep 06 '17 at 14:35
  • @Roberto You would have to wrap `linked_implementation.cpp` with include guards to avoid redefinition errors. – 0x5453 Sep 06 '17 at 14:38
  • @Roberto As 0x5453 said you'll get redefinition errors if you do. – NathanOliver Sep 06 '17 at 14:39
  • @NathanOliver I've edited the answer according to comments, thanks – Roberto Sep 06 '17 at 14:44
  • 1
    @Roberto No problem. Also note that `linked.h` needs include guards otherwise you'll have a infinite circular inclusion. Or you can just remove the `#include "linked.h"` from `linked_implementation.tpp` since it will never be compiled by itself. – NathanOliver Sep 06 '17 at 14:47
  • @NathanOliver removed the extra include – Roberto Sep 06 '17 at 14:56