I'm getting an undeclared identifier error (C2065 on vs2013) on my project, I managed to replicate the problem in the example code below:
foo.h:
#pragma once
#include "bar.h"
class Foo
{
public:
inline void doStuff() { someFunction(); }
};
bar.h:
#pragma once
#include <map>
#include "foo.h"
extern std::map<const char*, Foo> myMap;
void someFunction();
bar.cpp:
#include "bar.h"
std::map<const char*, Foo> myMap;
void someFunction()
{
}
main.cpp:
#include "foo.h"
int main()
{
Foo foo;
foo.doStuff();
return 0;
}
When building on Visual Studio Express 2013, it gives these errors:
error C2065: 'Foo' : undeclared identifier
error C2923: 'std::map' : 'Foo' is not a valid template type argument for parameter '_Ty'
error C3861: 'someFunction': identifier not found
What is the problem here and how can it be solved?
The problem is caused by circular dependency between foo.h and bar.h. It can be resolved using any of the following methods that I can think of.
Method 1
Foo
in bar.h.#include "foo.h"
in bar.h.foo.h:
#pragma once
#include "bar.h"
class Foo
{
public:
inline void doStuff() { someFunction(); }
};
bar.h:
#pragma once
#include <map>
// #include "foo.h"
class Foo;
extern std::map<const char*, Foo> myMap;
void someFunction();
Method 2
Foo::doStuff()
to foo.cpp.#include "bar.h"
in foo.h.foo.h:
#pragma once
class Foo
{
public:
void doStuff();
};
bar.h:
#pragma once
#include <map>
#include "foo.h"
extern std::map<const char*, Foo> myMap;
void someFunction();
foo.cpp:
#include "foo.h"
#include "bar.h"
void Foo::doStuff(){ someFunction(); }
Method 3
Use both Method 1 and Method 2.
foo.h:
#pragma once
class Foo
{
public:
void doStuff();
};
bar.h:
#pragma once
#include <map>
// #include "foo.h"
class Foo;
extern std::map<const char*, Foo> myMap;
void someFunction();
foo.cpp:
#include "foo.h"
#include "bar.h"
void Foo::doStuff(){ someFunction(); }
I strongly suggest using Method 3. As a general guide, it's better to use forward declarations in header files if you don't need the full definition of a class.