This looks more like a circular dependency problem than a template syntax problem. As long as you can define one class with the other incomplete, you can do something like:
// Begin testTemplateA.h
#ifndef TEST_TEMPLATE_A_H
#define TEST_TEMPLATE_A_H
template<typename A>
class testTemplateA
{
public:
testTemplateA(void) {}
~testTemplateA(void) {}
void callUponB(void); // Can't be defined here!
};
#include "testTemplateB.h"
template<typename A>
void testTemplateA<A>::callUponB(void) {
testTemplateB<A> g = testTemplateB<A>(this);
}
#endif
// End testTemplateA.h
// Begin testTemplateB.h
// Yes, the include is outside the define guard.
#include "testTemplateA.h"
#ifndef TEST_TEMPLATE_B_H
#define TEST_TEMPLATE_B_H
template<typename A>
class testTemplateB {
public:
typedef testTemplateA<A> templateType;
testTemplateB(templateType& TA) {}
~testTemplateB(void) {}
};
#endif
// End testTemplateB.h
If a source file includes just testTemplateA.h, it will see the class template definition for testTemplateA
, then include the entire contents of testTemplateB.h, then see the member definitions in testTemplateA.h that depend on testTemplateB
. If a source file includes just testTemplateB.h, it will immediately begin with testTemplateA.h, which will still include testTemplateB.h in the middle and get the same results. If a source file includes both in either order, the second one will have no effect since both have already been included.
You only need the typename
keyword like that in front of a name including at least one ::
token.
One other thing: your constructor testTemplateB(templateType& TA);
expects a reference, but your statement testTemplateB<A> g = testTemplateB<A>(this);
passes the pointer value this
.