1
votes

Consider the following example of a circular dependency.

The class Foo provides some static functionality:

//Foo.h
#pragma once

#include "T1.h" //causes circular dependency

class Foo
{
public:
    static void doSomething();

private:
    static T1<int> t1;
};



//Foo.cpp
#include "Foo.h"

void Foo::doSomething(){
}

A method of the template class T1 calls Foo::doSomething().

//T1.h
#pragma once


template<class T>
class T1
{
public:
    void doSomething(T t);
};

#include "T1.tcc"



//T1.tcc
#pragma once
#include "T1.h"

#include "Foo.h" //causes circular dependency

template<class T>
void T1<T>::doSomething(T t){
    Foo::doSomething();
}

Foo.h has to include T1.h because Foo contains an object of T1. T1.tcc has to include Foo.h because it calls a static member function of Foo. Because Foo.h is already protected by the include guard, Foo is not declared at this point (i guess).

../T1.tcc:9:5: error: ‘Foo’ has not been declared

From a design point of view, shouldn't this be perfectly legit because T1 does not contain an object of Foo?

I could probably store a pointer to T1 instead of holding the object by value, but in case that I do not want to store t1 on the heap, is there any other way to avoid this problem?

1

1 Answers

4
votes

static class data members can be declared without the definition of their type, so from Foo.h just replace:

#include "T1.h"

... with:

template<class T>
class T1;