Câu lệnh typedef này có nghĩa là gì?


76

Trong trang tham chiếu C ++, họ cung cấp một số ví dụ về typedef và tôi đang cố gắng hiểu ý nghĩa của chúng.

// simple typedef
typedef unsigned long mylong;


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

Vì vậy, typedef đơn giản (khai báo đầu tiên) tôi hiểu.

Nhưng họ đang khai báo điều gì với điều thứ hai (lặp lại bên dưới)?

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

Đặc biệt (&fp)(int, mylong)nghĩa là gì?


47
Cần lưu ý rằng viết một goo typedef một chữ cái như thế này là thực hành lập trình rất tệ, vì nó khó đọc và không có lợi ích gì từ nó. Vì vậy, nếu bạn đang đọc nó và chưa bao giờ thấy typedefs như thế này, vui lòng không bắt đầu sử dụng cú pháp này.
Lundin

3
@Lundin Tôi không đồng ý. Đặt tất cả chúng trên một dòng cho thấy rõ ràng rằng bạn có ý định để tất cả chúng tham chiếu đến cùng một loại cơ sở. Theo định nghĩa.
Mr Lister

9
@MrLister Nếu bạn viết chúng ở một dòng riêng biệt sau mỗi dòng, mỗi dòng sẽ bắt đầu bằng typedef some_type ...và bạn có vài dòng như vậy, ý định của bạn rất rõ ràng và không có chỗ cho các lỗi cú pháp. Dễ đọc hơn nhiều.
Lundin

2
@Lundin Có thể là vấn đề sở thích, vì vậy tôi không chắc liệu chúng ta có cần thảo luận về điều này hay không.
Mr Lister

Câu trả lời:


96

Nó khai báo một số typedef cùng một lúc, cũng như bạn có thể khai báo nhiều biến cùng một lúc. Chúng là tất cả các loại dựa trênint , nhưng một số được biến đổi thành các loại hợp chất.

Hãy chia nó thành các khai báo riêng biệt:

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
Trong suốt những năm lập trình C ++, tôi đã không biết điều đó! Tôi đoán người hướng dẫn của tôi không tin rằng cần phải học điều đó và tôi chưa bao giờ tìm thấy gì về nó. +1
John Odom

17
Người hướng dẫn của bạn đã đúng. Điều này khó đọc hơn, đó là một tính năng bạn không nên sử dụng.
Plutor

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

tương đương với:

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

Trên thực tế, có một ví dụ tương tự trong tiêu chuẩn C ++ 11:

C ++ 11 7.1.3 Bộ typedefđịnh nghĩa

A typedef-name không giới thiệu một kiểu mới như cách classkhai báo (9.1) hoặc enumkhai báo. Ví dụ: after

typedef int MILES , * KLICKSP ;

công trình xây dựng

MILES distance ;
extern KLICKSP metricp ;

là tất cả các khai báo đúng; loại khoảng cách là int mà metricplà "con trỏ tới int". —Gửi ví dụ


13
Theo sự hiểu biết của tôi thì câu trả lời là đúng. Tại sao có biểu quyết tiêu cực?
Dipto

32

Nếu bạn có cdecllệnh, bạn có thể sử dụng nó để làm sáng tỏ các khai báo này.

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

Nếu chưa có cdecl, bạn có thể cài đặt nó theo cách thông thường (ví dụ như trên hệ thống kiểu Debian, bằng cách sử dụng sudo apt-get install cdecl).


@athos Từsudo apt-get install cdecl
Amarghosh

ồ vậy nó không dành cho Windows?
athos

0

Phần (&fp)(int, mylong)đại diện cho một tham chiếu đến một hàm. Các lập trình viên không nên sử dụng các hàm typedefvì lý do bạn đang hỏi câu hỏi này. Nó gây nhầm lẫn cho những người khác khi nhìn vào mã.

Tôi đoán họ sử dụng typedeftrong một cái gì đó như thế này:

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;
}

Đã chỉnh sửa theo nhận xét của Brian:

int(&name)(...)là một tham chiếu hàm được gọi name(hàm trả về một int)

int &name(...)là một hàm được gọi là name trả về một tham chiếu đến một int

Tham chiếu đến một hàm trả về inttham chiếu sẽ trông giống như sau: typedef int &(&fp)(int, mylong)(điều này biên dịch trong một chương trình, nhưng hành vi chưa được kiểm tra).


3
Không, int&(int, mylong)là một loại khác với int(&)(int, mylong). Trước đây là một hàm trả về một tham chiếu đến int. Cái sau là một tham chiếu đến một hàm trả về int. Các tham chiếu đến các hàm rất khó hiểu và không hữu ích lắm, nhưng chúng tồn tại trong C ++.
Brian

Chắc chắn nó hơi phức tạp, nhưng thay thế là gì? Không sử dụng typedef? Bạn vẫn cần loại, nhưng không có typedef, bạn phải sử dụng rõ ràng cùng một loại hàm ở mọi nơi cần thiết, điều này khó hiểu hơn gấp mười lần và tất nhiên là dễ xảy ra lỗi. Thay vì phải lấy đúng một typedef, lập trình viên cần phải gõ đúng ở nhiều nơi.
gnasher729

2
"nó được đề nghị" bởi ai? Typedef cho con trỏ hàm rất thường được sử dụng trong nhiều API C cho các lệnh gọi lại và sử dụng typedef có nghĩa là hàm nhận con trỏ hàm làm tham số của nó dễ đọc hơn nhiều. Trừ khi bạn có thể sử dụng lambdas C ++, các typedef của con trỏ hàm là kiểu mã hóa IMO tốt hơn nhiều so với việc sử dụng chúng trực tiếp nếu bạn triển khai, ví dụ như API không đồng bộ.
uliwitness

-7

typedef đang xác định một kiểu mới để sử dụng trong mã của bạn, giống như cách viết tắt.

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

typename ở đây là cho trình biên dịch biết rằng value_type là một kiểu chứ không phải một đối tượng bên trong _MyBase.

:: là phạm vi của kiểu. Nó giống như "is in" nên value_type "nằm trong" _MyBase. hoặc cũng có thể được coi là chứa.

Có thể trùng lặp: C ++ - nghĩa của một câu lệnh kết hợp typedef và typename


10
Câu trả lời này không hữu ích. Câu hỏi nêu rõ rằng họ hiểu khái niệm cơ bản của một typedef(mà bạn đã giải thích) nhưng lại bối rối bởi một khái niệm phức tạp hơn (mà bạn thậm chí còn chưa chạm tới).
mirabilos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.