C++ 编译错误枚举“没有命名类型”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4032162/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ compilation error enum "does not name a type"
提问by Rémy DAVID
The following code:
以下代码:
foo.h
foo.h
#include "bar.h"
class foo{
public:
enum my_enum_type { ONE, TWO, THREE };
foo();
~foo() {}
};
foo.cpp
文件
foo::foo()
{
int i = bar::MY_DEFINE;
}
bar.h
酒吧.h
#include "foo.h"
class bar{
public:
static const int MY_DEFINE = 10;
foo::my_enum_type var;
bar() {};
~bar() {};
};
Makes g++ compiler complain about my_enum_type "does not name a type". Why ? All headers have multiple inclusion defines (not shown here for clarity).
使 g++ 编译器抱怨 my_enum_type “未命名类型”。为什么 ?所有标题都有多个包含定义(为清楚起见,此处未显示)。
Thanks
谢谢
采纳答案by CashCow
You must remove the cyclic dependency so you need to consider foo.cpp and foo.h as different units for this purpose.
您必须删除循环依赖,因此您需要为此目的将 foo.cpp 和 foo.h 视为不同的单位。
bar class definition must see foo::my_enum_type so probably bar.h including foo.h is a necessity.
foo class definition does not use any of bar, so foo.h does not need to include bar.h
foo.cpp does need to see bar for MY_DEFINE so foo.cpp should include bar.h. That would actually also bring in foo.h automatically but you may wish to include it anyway in foo.cpp, just in case you remove the dependency later.
bar 类定义必须看到 foo::my_enum_type 所以可能 bar.h 包括 foo.h 是必要的。
foo 类定义不使用任何 bar,因此 foo.h 不需要包含 bar.h
foo.cpp 确实需要看到 MY_DEFINE 的 bar,所以 foo.cpp 应该包含 bar.h。这实际上也会自动引入 foo.h,但您可能希望无论如何都将它包含在 foo.cpp 中,以防您稍后删除依赖项。
Presumably your headers have multiple include guards.
大概你的标题有多个包含守卫。
回答by Basilevs
Problems:
问题:
- no multiple inclusion protections
- cyclic inclusion
- type use before its declaration caused by cyclic inclusion
- 没有多重包含保护
- 循环包含
- 由循环包含引起的在声明之前使用类型
Your foo.h being processed by C preprocessor looks like infinite empty string sequence.
由 C 预处理器处理的 foo.h 看起来像无限空字符串序列。
With multiple inclusion protection foo.h is preprocessed to:
使用多重包含保护 foo.h 被预处理为:
> cpp foo.h
class bar{ // preprocessed from #include "bar.h"
public:
static const int MY_DEFINE = 10;
foo::my_enum_type var;
bar() {};
~bar() {};
};
// end of #include "bar.h"
class foo{
public:
enum my_enum_type { ONE, TWO, THREE };
foo();
~foo() {}
};
This obviously is not a valid C++ code - foo is used in bar body without previous declaration. C++, unlike Java, requires types to be declared before use.
这显然不是有效的 C++ 代码 - foo 在没有事先声明的情况下用于 bar body 中。与 Java 不同,C++ 要求在使用前声明类型。
- Use multiple inclusion protection. Depending on your platform those might be
#ifndef
macros or#pragma once
directives - Remove bar.h inclusion from foo.h.
- Place forward declarations where needed (in your case
bar
might be forward declared in foo.h, your example doesn't reveal neccesity of this though). - Move as much implementation as possible to *.cpp files.
- 使用多重包含保护。根据您的平台,这些可能是
#ifndef
宏或#pragma once
指令 - 从 foo.h 中删除 bar.h 包含。
- 在需要的地方放置前向声明(在您的情况下
bar
可能会在 foo.h 中进行前向声明,但您的示例并未显示这样做的必要性)。 - 将尽可能多的实现移至 *.cpp 文件。
If the situation can't be resolved with these recommendations, use PIMPL idiom.
如果这些建议无法解决这种情况,请使用PIMPL idiom。
In short - just remove #include "bar.h"
directive from foo.h
简而言之 - 只需#include "bar.h"
从 foo.h 中删除指令
回答by Armen Tsirunyan
foo()
{
int i = bar::MY_DEFINE;
}
should be
应该
foo::foo()
{
//...
}
Also note that
还要注意的是
static const int MY_DEFINE = 10;
is still a declaration, although it has an initializer. In bar.cpp you should have the following line
仍然是一个声明,尽管它有一个初始化程序。在 bar.cpp 中,您应该有以下行
const int bar::MY_DEFINE;
Also you can't include bar.h from foo.h and foo.h from bar.h... that's physically impossible :)
你也不能包含 foo.h 中的 bar.h 和 bar.h 中的 foo.h ......这在物理上是不可能的:)