我的项目中出现了未声明的标识符错误(vs2013上的C2065),我设法在下面的示例代码中复制了该问题:
foo.h中:
select t.name,
count(*) as num_managers
from employees m
join addresses a
on m.addressid = a.addressid
join towns t
on a.townid = t.townid
where exists (select 1 from employees x where x.managerid = m.employeeid)
group by t.name
order by 2 desc
bar.h:
#pragma once
#include "bar.h"
class Foo
{
public:
inline void doStuff() { someFunction(); }
};
bar.cpp:
#pragma once
#include <map>
#include "foo.h"
extern std::map<const char*, Foo> myMap;
void someFunction();
main.cpp中:
#include "bar.h"
std::map<const char*, Foo> myMap;
void someFunction()
{
}
在Visual Studio Express 2013上构建时,会出现以下错误:
错误C2065:'Foo':未声明的标识符
错误C2923:'std :: map':'Foo'不是参数'_Ty'的有效模板类型参数
错误C3861:'someFunction':找不到标识符
这里有什么问题,如何解决?
答案 0 :(得分:5)
您有循环定义问题。请注意,foo.h包括bar.h 和 bar.h包括foo.h.这不起作用,因为这意味着在第一个完成其他定义之前,两个定义都不能完成。您可以真正解决此问题的唯一方法是更改您的结构,以便其中一个标题不会{{1}}另一个标题。
答案 1 :(得分:1)
问题是由foo.h和bar.h之间的循环依赖引起的。它 可以使用我能想到的任何以下方法解决。
方法1
Foo
的前向声明。#include "foo.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();
方法2
Foo::doStuff()
的实现移至foo.cpp。#include "bar.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(); }
方法3
同时使用方法1 和方法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(); }
我强烈建议使用方法3 。作为一般指南,最好是 如果您不需要完整,请在头文件中使用前向声明 一个类的定义。