Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 转发未命名结构的声明_C++_C_Struct_Typedef_Forward Declaration - Fatal编程技术网

C++ 转发未命名结构的声明

C++ 转发未命名结构的声明,c++,c,struct,typedef,forward-declaration,C++,C,Struct,Typedef,Forward Declaration,赏金问题:那么,这两个Foo不是一回事。好的第二种形式在图书馆中给出。如果我不能更改它,我如何转发声明它 我一直认为C和C++允许重复声明,只要没有重复的定义。当我试图编写C++代码时,遇到了这个问题,扩展了C库。 struct Foo; typedef struct {} Foo; 这会产生以下错误: “struct Foo”以前的声明为“struct Foo” 我要转发声明,该死!这里怎么了?您正在用相同的名称声明两个不同的实体。第一个名为struct Foo,是一个名为Foo的结构。第

赏金问题:那么,这两个
Foo
不是一回事。好的第二种形式在图书馆中给出。如果我不能更改它,我如何转发声明它


<>我一直认为C和C++允许重复声明,只要没有重复的定义。当我试图编写C++代码时,遇到了这个问题,扩展了C库。

struct Foo;
typedef struct {} Foo;
这会产生以下错误:

“struct Foo”以前的声明为“struct Foo”


我要转发声明,该死!这里怎么了?

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

如果您这样做:

struct Foo;
struct Foo {};
它是有效的,因为在这两种情况下都声明了名为
Foo
的结构


不能转发声明匿名结构。剩下两个选择:包括整个定义,或者更改标题和结构名称。

转发声明声明将有一个名为
Foo
struct


您的第二个声明是名为
Foo
typedef
。这些不是同一件事。

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

struct Foo;     // Forward declaration

struct Foo 
{

}; // Definition
如果您想在C中仅调用它
Foo
,而不是
struct Foo
,您确实需要typedef,这也可以通过不同的方式实现:

struct Foo;     /* Forward declaration */

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

}; /* Definition */
typedef struct Foo Foo;  /* typedef */


当然可以在C和C++中使用表单<代码> StuttFoo< /Cuth.< /P> < P>对于TyPulf的前向声明,您需要引用正在被Type填充的东西,如:

struct foo;
typedef foo bar;
class foo{};
因为您想要正向声明匿名结构,所以您既不能在原始实体的正向声明中为它命名,也不能在类型定义时引用它。“逻辑”语法为:

struct ;
typedef bar;
class {};
但由于这显然是不可能的,所以不能向前声明匿名结构

要使用standardese,请看9.1-2:

仅由类密钥标识符组成的声明;要么是一个 在当前作用域或转发中重新声明名称 将标识符声明为类名。它介绍了这门课 将名称添加到当前范围中

没有标识符,没有转发声明


一句话:避免匿名结构,除非它们给了你真正需要的优势。

IMHO,只需将你的
typedef
更改为

typedef struct Foo {} Foo;
              ^^^^^
不存在危害,在C+C++中仍适用。现在你可以向前申报了

[注意:如果您仍然坚持根本不触摸
typedef
,那么下面是一个肮脏的把戏


只有当
Foo.h
只包含1个
struct
声明时,这才有效。我不推荐它。]

键入匿名结构是一种早于C++03的做法,主要是为了保持与C99之前编译器的兼容性


假定这是2011,C++和C都改变了,我想知道为什么没有这样一个库的最新版本! 如果它不再处于开发阶段,你就不能“离开”,而只是“生存”和改变,这是实现这一目标的方法。 如果仍在部署中,请将问题提交给开发团队

如果您需要一个解决方案,请考虑该结构可以继承。 所以,写一个向前的声明,比如

struct MyFoo;
并将其定义为

#include "old_library.h"
struct MyFoo: public Foo {};

在所有代码中,忘记
Foo
,始终使用
MyFoo

您的特定编译器可能会产生不同

使用MinGW GCC 3.4.5,两个声明编译时都没有错误或警告(使用
-Wall

库中是否可能已经存在转发声明?例如,要允许使用循环指针,请执行以下操作:

struct Foo;
typedef struct Foo {
    struct Foo *fooPtr;
} Foo;

如果库标题中已经存在此错误,则会导致您描述的错误。

为什么不直接避免转发decl呢


如果第二个定义在头文件中,可以在C++头文件中首先包含头文件。将C++看作是C标头,包含了包含“代码”>“外部”“C”{<代码> >代码> }/C>在大多数情况下都是足够的。

< p>因为它的未命名,所以不能向前声明它。它是一个未命名的结构,Foo是一个typedef。

您正在尝试键入以前使用过的名称。该语句完全有效,只需使用其他名称即可

struct Foo; // Forward declaration of struct Foo
typedef struct {} anotherFoo; // Another structure typedefed
struct Foo {
 // Variables
}; // Definition of the forward declared Foo.

请注意,typedef不能用在同一个名称中。

在类似的情况下,我有一个带有类似

== old_library.h ==
typedef struct { int data; } Foo;
== /old_library.h ==
我在自己的C++类中使用它,作为私有方法的参数:

class C {
  void run(Foo *ds);
  ...
}
为了避免从C.hpp中包含“old#u 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

我想我最近遇到了与原始海报相同的问题,并已解决如下问题:

我正在围绕第三方提供的API编写一个包装器,定义如下:

Foo.h:

typedef struct _foo 
{
    int i;
} Foo;

Foo* MakeFoo();
int UseFoo(Foo* foo);
我的包装器需要有Foo作为成员,但我不想向我的包装器的所有使用者公开Foo

UberFoo.h:

#pragma once

struct _foo;  // forward declare the actual type _foo, not the typedef Foo

class UberFoo
{
public:
    UberFoo();
    int GetAnswer();
private:
    _foo* f;
};
UberFoo.cpp:

#include "UberFoo.h"
#include "Foo.h"

UberFoo::UberFoo()
{
    this->f = MakeFoo();
}

int UberFoo::GetAnswer()
{
    return UseFoo(f);
}
现在,我的类的使用者可以实例化它,而无需访问_foo/foo的实际定义。如果我需要将指针作为参数传递给\u foo,或者从函数返回它们,并且需要有一个成员_foo,那么这也会起作用

main.cpp:

#include <cstdio>
#include "UberFoo.h"

int main(int argc, char* argv[])
{
    UberFoo u;
    printf( "The Answer = %d\n", u.GetAnswer());
    return 0;
}

希望这有帮助

编译器是什么?另外,可能是空声明让它感到困扰?没有所谓的“C/C++”语言,特别是在结构上下文中。有太多的C++作者把代码“乱扔”在代码上,就像它是1989。@ Kerrek,在C++代码中没有什么错误。<代码>结构代码>代码,我用它来指示我写的是一个未封装的POD类型。@ SpAFF:我想Kerrek是指C“ID”。
typedef struct _foo 
{
    int i;
} Foo;

Foo* MakeFoo();
int UseFoo(Foo* foo);
#pragma once

struct _foo;  // forward declare the actual type _foo, not the typedef Foo

class UberFoo
{
public:
    UberFoo();
    int GetAnswer();
private:
    _foo* f;
};
#include "UberFoo.h"
#include "Foo.h"

UberFoo::UberFoo()
{
    this->f = MakeFoo();
}

int UberFoo::GetAnswer()
{
    return UseFoo(f);
}
#include <cstdio>
#include "UberFoo.h"

int main(int argc, char* argv[])
{
    UberFoo u;
    printf( "The Answer = %d\n", u.GetAnswer());
    return 0;
}
typedef struct // the actual struct type underlying the typedef is anonymous here
{
    int i;
} ThisWontWork;