我最近遇到了这样的情况:
class A
{
public:
typedef struct/class {...} B;
...
C::D *someField;
}
class C
{
public:
typedef struct/class {...} D;
...
A::B *someField;
}
Run Code Online (Sandbox Code Playgroud)
通常你可以声明一个类名:
class A;
Run Code Online (Sandbox Code Playgroud)
但是你不能转发声明一个嵌套类型,以下导致编译错误.
class C::D;
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
我在Objective-C程序中遇到enum可见性问题.我有两个头文件,一个定义了一个typedef enum.另一个文件需要使用typedef'd类型.
在直接C中,我只是#include其他头文件,但在Objective-C中,建议不要#import在头文件之间使用,而是@class根据需要使用前向声明.但是,我无法弄清楚如何转发声明枚举类型.
我不需要实际的枚举值,除了相应的.m实现文件,我可以安全地#import离开.那么如何才能typedef enum在标题中识别?
鉴于该计划:
enum E : int
{
A, B, C
};
Run Code Online (Sandbox Code Playgroud)
g++ -c test.cpp工作得很好.但是,clang++ -c test.cpp出现以下错误:
test.cpp:1:6: error: ISO C++ forbids forward references to 'enum' types
enum E : int
^
test.cpp:1:8: error: expected unqualified-id
enum E : int
^
2 errors generated.
Run Code Online (Sandbox Code Playgroud)
这些错误消息对我没有任何意义.我在这里看不到任何前瞻性参考.
在重构一些旧代码时,我已经删除了一些实际上应该是静态的公共方法,因为它们a)不对任何成员数据进行操作或调用任何其他成员函数和b)因为它们可能在其他地方证明是有用的.
这让我想到了将"帮助"功能组合在一起的最佳方法.Java/C#方式是将一类静态函数与私有构造函数一起使用,例如:
class Helper
{
private:
Helper() { }
public:
static int HelperFunc1();
static int HelperFunc2();
};
Run Code Online (Sandbox Code Playgroud)
但是,作为C++,您还可以使用命名空间:
namespace Helper
{
int HelperFunc1();
int HelperFunc2();
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,我认为我更喜欢命名空间方法,但我想知道每种方法的优缺点.例如,如果使用类方法,是否会有任何开销?
我正在尝试为枚举使用正确的前向声明.因此,我搜索了互联网,但我找不到有用的东西.
我在标题中使用:
// Forward declaration
enum myEnumProcessState;
Run Code Online (Sandbox Code Playgroud)
然后我在结构中使用这个枚举:
struct myStruct {
[...]
myEnumProcessState osState;
[...]
};
Run Code Online (Sandbox Code Playgroud)
在另一个标题中:
enum myEnumProcessState {
eNotRunning,
eRunning
};
Run Code Online (Sandbox Code Playgroud)
我发现这个类型应该放在enum forward声明中才能被接受.但是,我不知道我应该为流程状态添加哪种"类型".这些不起作用:
enum myEnumProcessState : unsigned int;
enum myEnumProcessState : String;
Run Code Online (Sandbox Code Playgroud)
我想跳过前方声明,但我的结构正在哭,因为它再也找不到它了......
所以我有点困惑.你知道解决方案吗?
非常感谢 :)
我知道,一般来说,我们可以在 C++11 中前向声明枚举。
那么,为什么会这样:
enum kind_t { kind1, kind2 };
template <kind_t Kind> struct foo {};
template <> struct foo<kind1> {
enum named : int;
};
enum foo<kind1>::named : int {
named1 = 123,
named2 = 456,
};
Run Code Online (Sandbox Code Playgroud)
使用 GCC (12.1) 编译失败?错误是(上帝螺栓):
<source>:9:6: error: cannot add an enumerator list to a template instantiation
9 | enum foo<kind1>::named : int {
| ^~~~~~~~~~
ASM generation compiler returned: 1
<source>:9:6: error: cannot add an enumerator list to a …Run Code Online (Sandbox Code Playgroud) 我搜索了前方声明,并没有看到任何方法让我的情况有效.所以这里是:
1)有一个C头文件,一个导出接口,可以说是一个包含枚举类型的大型多组件软件
"export.h":
// This is in "C"!
typedef enum _VM_TYPE {...., ...., ...,} VM_TYPE;
Run Code Online (Sandbox Code Playgroud)
2)C++中的部分代码使用该导出.
"cpp_code.cpp":
// This is in C++
#include "export.h"
#include "cpp_header.hpp"
{ .... using VM_TYPE values to do stuffs....}
Run Code Online (Sandbox Code Playgroud)
"cpp_header.hpp":
// Need to somehow forward declear VM_TYPE here but how?
Struct VM_INFO {
....
VM_TYPE VType; //I need to add this enum to the struct
....
};
Run Code Online (Sandbox Code Playgroud)
很明显,问题出在cpp_head.hpp中,因为它不知道枚举.
我尝试添加到cpp_header.hpp
typedef enum _VM_TYPE VM_TYPE;
Run Code Online (Sandbox Code Playgroud)
它实际上会起作用.那为什么这个有用呢?因为它有C风格的语法?!无论如何,我被告知不要通过上层"管理"这样做("它是C++,而不是C").
是否还有其他方法可以根据当前的事物联系方式完成这项工作?他们不想更改/添加包含文件; "枚举类"只是c ++,对吗?仅将"enum VM_TYPE"添加到cpp_header.hpp将会出现有关重新定义的错误. …
我在C++ 11中工作,包括用C++ 03实现的h文件.在h文件中我包含了枚举的枚举Foo.我想申报一个转发code.h并将其用于code.cpp:
header.h:
enum Foo {A=1};
Run Code Online (Sandbox Code Playgroud)
code.h:
enum Foo : int; // also tried : unsigned int, long, short, unsigned short, char, unsigned char
void bar(Foo foo);
Run Code Online (Sandbox Code Playgroud)
code.cpp:
#include header.h
void bar(Foo foo) { }
Run Code Online (Sandbox Code Playgroud)
这是我编译时得到的错误(测试g ++ 4.8.5和g ++ 5.3.1):
In file included from code.cpp:2:0:
header.h:1:6: error: underlying type mismatch in enum ‘enum Foo’
enum Foo {A=1};
^
In file included from code.cpp:1:0:
code.h:3:12: error: previous definition here
enum Foo : int;
Run Code Online (Sandbox Code Playgroud)
如果我将header.h更改为:我可以修复此错误: …
第一部分:
我已经研究了一些细节opaque-enum-declaration s和elaborated-type-specifier已经有几天了,我真的希望有人来证实这一点.GCC和VS2013不编译此代码(clang确实如此),我认为clang符合§7.1.6.3/ 1,因为它enum E是一个不是声明唯一组成部分的详细类型说明符enum E e = E::b;.我的分析是否正确?
#include <iostream>
enum class E : char {a = 'a', b};
int E;
enum E e = E::b; // Doesn't compile in GCC and VS2013
int main()
{
std::cout << (char)(e) << '\n';
}
Run Code Online (Sandbox Code Playgroud)
第二部分:
下面的代码段与上面的代码段非常类似,不会编译.我理解为什么它没有(详细说明类型说明符 enum E是声明的唯一组成部分enum E;,§7.1.6.3/ 1不允许这样做).我想知道的是为什么编译器不能接受这种结构?
#include <iostream>
enum class E : char {a = 'a', b};
int E;
enum E; // This doesn't …Run Code Online (Sandbox Code Playgroud) 你不能在C++中转发声明枚举,但你可以在C中.
对于使用某些C++代码的C代码库,有没有办法在C中使用前向声明的枚举,当在C++中使用该头时(extern "C" {..}块内)不会导致错误?
例:
extern "C" {
enum MyEnum;
}
int main() { return 0; }
Run Code Online (Sandbox Code Playgroud)
GCC给出错误:
error: use of enum ‘MyEnum’ without previous declaration
enum MyEnum;
^~~~~~
Run Code Online (Sandbox Code Playgroud)
Clang也失败了:
error: ISO C++ forbids forward references to 'enum' types
enum MyEnum;
Run Code Online (Sandbox Code Playgroud)
为了给出一些上下文,这是一个主要是C代码库,其中一个小的C++模块碰巧包含C代码的头.我可以做一些破解让C++忽略枚举,但是想知道在这种情况下C++是否可以使用C头.
更新:已经注意到官方的C规范不支持这一点,但是它似乎是一些最广泛使用的编译器中的事实上的标准:GCC/CLANG/MSVC.