未命名结构的前向声明

spr*_*aff 41 c c++ struct typedef forward-declaration

赏金问题:所以,这两个Foo不是一回事.精细.第二种形式在图书馆中给出.鉴于我无法改变它,我该如何转发声明呢?


我一直以为C和C++允许重复声明,前提是没有重复的定义.然后我在尝试编写扩展C库的C++代码时遇到了这个问题.

struct Foo;
typedef struct {} Foo;
Run Code Online (Sandbox Code Playgroud)

这会出现以下错误:

'struct Foo'之前的声明为'struct Foo'

我想转发声明,嘲笑它!这有什么不对?

R. *_*des 40

您正在声明两个具有相同名称的不同实体.第一个struct Foo是名为的结构Foo.第二个是匿名结构的别名.

如果你这样做:

struct Foo;
struct Foo {};
Run Code Online (Sandbox Code Playgroud)

它有效,因为你Foo在两种情况下都声明了一个结构体.

您无法转发声明匿名结构.您有两个选择:包括整个定义,或更改标题并命名结构.

  • 对于OP,您也无法转发声明typedef. (3认同)

Emi*_*lia 38

typedef-ing anonymous struct是一种在C++ 03之前的实践,主要是为了保持与C99之前的编译器的兼容性.

鉴于这是2011年,并且C++和C都发生了变化,我想知道为什么没有更多这样的库的最新版本!

如果它不再处于开发阶段,你就不能"离开",而只是"生存"并改变它就是这样做的方法.如果仍在部署中,请将问题提交给开发团队.

如果需要解决方法,请考虑该结构可以继承.所以,写一个前进声明就像

struct MyFoo;
Run Code Online (Sandbox Code Playgroud)

并将其定义为

#include "old_library.h"
struct MyFoo: public Foo {};
Run Code Online (Sandbox Code Playgroud)

在您的所有代码中,忘记Foo并始终使用MyFoo.

  • 在类似的情况下,我有一个遗留的C头,类似于== old_library.h == typedef struct {int data; Foo; == /old_library.h ==我在我自己的C++类中使用它作为私有方法的参数:class C {void run(Foo*ds); ...}为了避免来自C.hpp的#include"old_library.h",我使用以下前向声明:class C {struct Foo; void run(Foo*ds); ...}和C.cpp我有以下语句:extern"C"{#include"old_library.h"} struct C :: Foo:public :: Foo {}; 这样,我透明地使用C :: Foo而不是Foo,并且不需要MyFoo! (2认同)

Ale*_*ohn 11

在类似的情况下,我有一个遗留的C头像

== old_library.h ==
typedef struct { int data; } Foo;
== /old_library.h ==
Run Code Online (Sandbox Code Playgroud)

我在我自己的C++类中使用它作为私有方法的参数:

class C {
  void run(Foo *ds);
  ...
}
Run Code Online (Sandbox Code Playgroud)

为了避免C.hpp的#include"old_library.h",我使用以下前向声明:

class C {
  struct Foo;
  void run(Foo *ds);
  ...
}
Run Code Online (Sandbox Code Playgroud)

在C.cpp我有以下声明:

extern "C" {
#include "old_library.h"
}
struct C::Foo : public ::Foo {};
Run Code Online (Sandbox Code Playgroud)

这样,我透明地使用C :: Foo而不是Foo,并且不需要MyFoo!


mol*_*ilo 8

您不需要在C++中键入def结构:

struct Foo;     // Forward declaration

struct Foo 
{

}; // Definition
Run Code Online (Sandbox Code Playgroud)

如果你想调用它只是Foo代替struct Foo在C,你所需要的类型定义,它也可以以不同的方式进行:

struct Foo;     /* Forward declaration */

struct Foo /* The name is needed here */
{

}; /* Definition */
typedef struct Foo Foo;  /* typedef */
Run Code Online (Sandbox Code Playgroud)

要么

struct Foo;     /* Forward declaration */

typedef struct Foo /* The name is needed here */
{

} Foo; /* Definition and typedef combined */
Run Code Online (Sandbox Code Playgroud)

您当然可以struct Foo在C和C++中使用该表单.


Oli*_*rth 5

你的前瞻性声明声明会有一个struct被叫Foo.

你的第二个声明属于typedef被叫Foo.这些都不是一回事.