这个typedef语句是什么意思?

77

在C++的参考页面中,他们提供了一些typedef示例,我正在尝试理解它们的含义。

// simple typedef
typedef unsigned long mylong;


// more complicated typedef
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

所以我理解第一个声明中的简单typedef。

但是第二个声明(如下重复)他们在声明什么?

typedef int int_t, *intp_t, (&fp)(int, ulong), arr_t[10];

(&fp)(int, mylong)这个表达式特别是什么意思?


48
需要注意的是,编写像这样的一行式typedef goo非常不好的编程实践,因为它很难阅读,并且没有任何优势。因此,如果您正在阅读本文并且从未见过这样的typedef,请不要开始使用此语法。 - Lundin
3
我不同意。将它们放在同一行中可以清楚地表明您打算让它们都指向相同的基本类型。从定义上讲。 - Mr Lister
10
如果你把它们分别写在不同的行上,每一行都以 typedef some_type... 开头,而且这样的行有多行,那么你的意图非常清晰,语法错误的余地几乎不存在。这会更易读。 - Lundin
2
@Lundin 这可能是个品味问题,所以我不确定我们是否需要讨论这个。 - Mr Lister
5个回答

96

它一次声明了多个typedef,就像你可以一次声明多个变量一样。它们都是基于int的类型,但有些被修改成了复合类型。

让我们把它分解成单独的声明:

typedef int int_t;              // simple int
typedef int *intp_t;            // pointer to int
typedef int (&fp)(int, ulong);  // reference to function returning int
typedef int arr_t[10];          // array of 10 ints

5
我多年编写C++程序,竟然不知道这个!我猜我的讲师认为这并不是必须学习的内容,而我也从未找到相关资料。+1 - John Odom
17
您的讲师是正确的。这个功能更难阅读,你不应该使用它。 - Plutor

42
typedef int int_t, *intp_t, (&fp)(int, mylong), arr_t[10];

等同于:

typedef int int_t;
typedef int *intp_t;
typedef int (&fp)(int, mylong);
typedef int arr_t[10];

实际上,在C++11标准中有一个类似的例子:

C++11 7.1.3 The typedef specifier

typedef名称不像class声明(9.1)或enum声明那样引入新类型。例如:在下面的代码之后

typedef int MILES , * KLICKSP ;

这些建筑物

MILES distance ;
extern KLICKSP metricp ;

are all correct declarations; the type of distance is int that of metricp is “pointer to int.”—end example

以上都是正确的声明;distance 的类型是 int,metricp 的类型是“指向 int 的指针”。—示例结束


13
据我理解,答案是正确的。为什么会有负投票? - Dipto

32

如果你有cdecl命令,你可以使用它来解密这些声明。

cdecl> explain int (&fp)(int, char)
declare fp as reference to function (int, char) returning int
cdecl> explain int (*fp)(int, char)
declare fp as pointer to function (int, char) returning int

如果您没有 cdecl,通常可以通过安装来获取(例如,在 Debian 系统上使用 sudo apt-get install cdecl)。


@athos 从 sudo apt-get install cdecl - Amarghosh
哦,那它不是为Windows设计的? - athos

0

(&fp)(int, mylong) 部分表示对函数的引用。不建议程序员在 typedef 中使用函数,正是因为你提出了这个问题。这会让其他人在查看代码时感到困惑。

我猜他们在类似以下的情况下使用 typedef

typedef unsigned long mylong; //for completeness
typedef int (&fp)(int, mylong);
int example(int param1, mylong param2);

int main() {
     fp fp_function = example;
     int x = fp_function(0, 1);
     return 0;
}

int example(int param1, mylong param2) {
     // does stuff here and returns reference
     int x = param1;
     return x;
}

根据Brian的评论进行编辑:

int(&name)(...)是一个名为name函数引用(该函数返回一个int)

int &name(...)是一个名为name的函数,返回一个int的引用

返回一个引用到返回int的函数可能会像这样:typedef int &(&fp)(int, mylong)(这在程序中可以编译,但行为未经测试)。


3
不,int&(int, mylong)int(&)(int, mylong)是不同的类型。前者是返回对int的引用的函数。而后者是返回int的函数的引用。函数的引用在C++中并不常见且不太有用,但它们确实存在。 - Brian Bi
当然,这有点复杂,但是还有什么选择呢?不使用typedef吗?你仍然需要该类型,但是没有typedef,你必须在需要的每个地方显式地使用相同的函数类型,这会更加混乱,并且容易出错。程序员需要在许多地方正确获取类型,而不是只需正确获取一个typedef。 - gnasher729
2
“建议”来自谁?函数指针的typedef在许多C API中用于回调,使用typedef意味着以函数指针作为参数的函数更易读。除非您可以使用C++ lambda,否则在实现异步API时,函数指针typedef比直接使用它们要好得多。在我的看法中,这是更好的编程风格。 - uliwitness

-7

typedef 是在编程中定义新类型的一种方式,就像是一种简写。

typedef typename _MyBase::value_type value_type;
value_type v;
//use v

这里的typename让编译器知道value_type是一个类型而不是_MyBase内部的对象。

::是类型的作用域。它有点像“在...之中”,所以value_type“在”_MyBase中。或者也可以理解为包含。

可能重复:C++ - 合并typedef和typename语句的含义


10
这个回答没有帮助。问题清楚地说明他们理解 typedef 的基本概念(你已经解释了),但对更复杂的部分感到困惑(你甚至没有涉及)。 - mirabilos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接