【问题标题】:Can I typedef unnamed struct/class in c++?我可以在 C++ 中 typedef 未命名的结构/类吗?
【发布时间】:2020-08-15 10:47:40
【问题描述】:

在 C 中,我可以 typedef unnamed (no tag) struct:

typedef struct {
 int val;
} Foo_t;

但是当我尝试在 c++ 中做同样的事情时:

typedef struct
{
    A(int a) : a_var(a) {}
    int a_var;
} A;

typedef struct : public A
{
    B(int a, int b) : A(a), b_var(b) {}
    int b_var;
} B;

B &getB()
{
    static B b(1, 2);
    return b;
}
int main() {}

输出

error: ISO C++ forbids declaration of ‘A’ with no type
error: only constructors take member initializers
error: class ‘<unnamed struct>’ does not have any field named ‘A’

我知道我正在使用“未命名”结构的构造函数A(int a),但紧随其后的是typedefed。所以构造函数只能用于知道类型

【问题讨论】:

  • 您的标题问题与说明中隐含的问题不匹配。

标签: c++ struct language-lawyer typedef


【解决方案1】:

例如这个 typedef 声明的问题

typedef struct
{
    A(int a) : a_var(a) {}
    int a_var;
} A;

是在未命名的结构中使用未声明的名称 A 作为构造函数的名称。所以这个声明是无效的。

顺便说一句,C 中的其他地方也存在同样的问题。

例如,考虑一个用于定义链表节点的结构的 typedef 声明。

typedef struct
{
    int data;
    A *next;
} A;

同样,结构定义中的名称 A 未定义。

即使你会这样写

typedef struct A
{
    int data;
    A *next;
} A;

尽管如此,名称 A 仍未在 C 结构中声明。您必须用 C 编写

typedef struct A
{
    int data;
    struct A *next;
} A;

另一方面,在 C++ 中,这样的 typedef 声明是有效的。

【讨论】:

  • 我在我的帖子中提到了它(最后 - 构造函数只能用于知道类型),但这破坏了与 C 的兼容性(当然 - c 结构没有构造函数)跨度>
  • @milanHrabos 的重点是在您的示例中不是“在 C++ 中做同样的事情”
  • @idclev463035818 启用未知类型的唯一方法是通过指针(知道它们的大小),但我无法在c++ 中创建函数指针构造函数,例如(*A)(int) 为了使构造函数成为未知类型成为可能。 C++ 应添加此功能以保持与 C 的兼容性
  • @milanHrabos 我不太明白。你能提供一个兼容性被破坏的例子吗?您的示例是 C++,因此 C 兼容性不是问题
  • @idclev463035818 你说A is undefined,你是对的。该类型是未知的,因此唯一可能(并且在C 中可用)的解决方案是使用该类型A* 的指针。但是该类型在 construction 中使用,您 cannot 使用指针(例如,使其成为函数指针),而在 C 中,您可以(当然对于普通函数,C没有结构)。这就是兼容性被破坏的情况
【解决方案2】:

是的,你可以,但不能像你说的那样在结构中使用类型名称。

// this is valid
typedef struct{
   int x;
   void set(int n){x=n;}
} A;

// this is not
typedef struct{
    int x;
    B(int n){x = n;}
} B;

// you can only have constructor with named structs
typedef struct st_C{
    int x;
    st_C(int n){x = n;}
} C;

// this is valid
C *foo = new C(3); 

【讨论】:

    【解决方案3】:

    在 C 中,您经常必须像这样编写 typdef:

    typedef struct {
     int val;
    } Foo_t;
    

    为了避免不得不写

    struct Foo_t f;
    

    每一次,很快就会变得很乏味。

    在 C++ 中,所有 structs unions 和 enums 声明的行为就像它们是隐式 typedefed。所以你可以像这样声明一个结构:

    struct A
    {
        A(int a) : a_var(a) {}
        int a_var;
    };
    

    但是,C++ 中的结构通常是聚合(数据的简单集合),您不需要构造函数。所以以下是可以的:

    struct A
    {
        int a_var;
        int b_var;
    };
    

    构造函数由编译器隐式定义,当你使用带有大括号的值初始化时:

    A a{};
    

    结构的所有成员都将被清零。

    【讨论】:

      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2013-07-17
      • 1970-01-01
      • 2023-03-29
      • 2011-03-31
      • 2010-10-09
      • 2018-07-11
      相关资源
      最近更新 更多