【问题标题】:Please explain syntax rules and scope for "typedef"请解释“typedef”的语法规则和范围
【发布时间】:2011-01-26 12:44:37
【问题描述】:

规则是什么? OTOH 简单的案例似乎暗示新类型是一行的最后一件事。像这里Uchar是新类型:

typedef unsigned char Uchar;

但是函数指针完全不同。这里的新类型是pFunc

typedef int (*pFunc)(int);

我想不出任何其他的例子,但我遇到了一些非常令人困惑的用法。

那么是否有规则,或者人们只是应该从经验中知道这是如何完成的,因为他们以前见过这样做?

另外:typedef 的范围是什么?

【问题讨论】:

  • 也可能想研究typedef typename 构造
  • “那么有规则吗” - 不,我们只是在进行过程中编写语法。然后编译器读取我们的想法以了解我们的意思。
  • @aaa: typedef typename 构造? typename 在模板中用于消除类型的歧义。这将是一种类型的一部分;它不是typedef 的特殊形式。
  • 这就像说你想研究typedef class 构造。
  • C++11 的别名声明(带有using 的类型定义)更具可读性,尤其是函数指针。它们对于模板化的 typedef 也是必需的。所以,你可能也想看看那些。一个好的指南是msdn.microsoft.com/en-CA/library/dn467695.aspx

标签: c++ c function-pointers typedef


【解决方案1】:

基本上,typedef 与对象声明的语法完全相同,只是它的前缀为 typedef。这样做会改变声明的含义,以便新标识符声明对象类型的别名,如果它是一个正常的声明,则该对象将拥有。

typedef 的作用域与对象声明的完全一样,因此它可以是文件作用域或块的局部区域,或者(在 C++ 中)命名空间或类。

例如

声明一个int

int a;

声明一个类型是int 的别名:

typedef int a_type;

声明一个指向char的指针:

char *p;

声明char * 的别名:

typedef char *pChar;

声明一个函数指针:

int (*pFn)(int);

为“指向采用int并返回int的函数的指针”类型声明一个别名:

typedef int (*pFunc)(int);

【讨论】:

  • 它也适用于任何类型的简单声明(不仅适用于对象声明)。也适用于函数声明:typedef void foo();
  • 辉煌;显示了 OP 看不到的语法的一致性。
  • @litb:绝对正确。为了简单起见,我忽略了它。
  • 谢谢。这很清楚。看来我让事情变得比实际复杂得多。
【解决方案2】:

为了语法方便,typedef 被视为存储类说明符,如externstaticregister。语义上当然有很大的不同,但是当typedef 被添加到语言中时,使用现有的语法片段来定义它的语法会更简单。

static 添加到对象声明中不会改变声明的含义除了它将对象的存储类更改为“静态”(如果还没有的话):

{
    int foo; /* automatic storage duration */
    static int bar; /* static storage duration */
}

static 替换为typedef 会改变声明的含义,因此定义的名称不是对象名称而是类型名称(实际上只是现有类型的别名):

    typedef int baz; /* "baz" is an alias for "int" */

同样的语法适用于更复杂的声明:

int (*a)[42];         /* a is a pointer to an array of 42 ints */
static int (*b)[42];  /* Same as a, but with static storage duration */
typedef int (*c)[42]  /* c is an alias for the type int(*)[42], or 
                         "pointer to array of 42 ints" */

一旦你意识到typedef 被任意推入externstaticregister 占用的语法中的同一槽中,理解typedef 声明并不难(也不容易!)理解对象声明。 (cdecl 程序和web site 对于解包复杂的声明很有用。)

您还可以将typedef 用于函数类型:

void func(void);              /* declare func as a function */
typedef void func_type(void); /* declare func_type as a name
                                 for a function type */

您不能使用typedefed 函数类型来声明或定义函数,但可以使用它来声明函数指针:

func_type *ptr = func;

至于范围(意思是声明标识符可见的程序文本区域),由typedef 声明定义的标识符与任何其他声明标识符具有相同的范围。如果它是在文件范围内声明的,在任何函数之外,它从声明点到文件末尾都是可见的。如果它是在函数内声明的,则从声明它的点到最近的封闭块的末尾都是可见的。和任何声明一样,它可以被内部范围内的另一个同名声明隐藏。

【讨论】:

  • 这个答案应该有更多的支持,因为它解释了范围问题(来到这里只是为了那个)
  • @J3STER:谢谢,但接受的答案也涉及范围。
  • 哦,你是对的,我完全错过了,(轻度阅读障碍)
  • 那么,当两个具有相同名称(指定不同事物)的typedefs 生活在不同的翻译单元中时,会发生ODR 违规吗?简而言之,我应该将文件范围 typedefs 放在未命名的命名空间中,就像我对本地(在源文件中声明和定义)类所做的一样。
【解决方案3】:

只是因为没有其他人提到它:它总是本地化到任何对象构建。因此,如果您使用相同的 using/typedef 名称编译不同的 cpp 文件,那么它们将不会相互影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 2013-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多