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


Trong trang tham chiếu C ++, chúng cung cấp một số ví dụ typedef và tôi đang cố 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ọ tuyên bố cái gì với cái thứ hai (lặp lại dưới đây)?

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

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


76
2018-02-27 07:23


gốc


Cần lưu ý rằng viết một typedef goo một lớp như thế này là thực hành lập trình rất xấu, bởi vì nó khó đọc và không có lợi thế gì từ nó. Vì vậy, nếu bạn đang đọc này và chưa bao giờ thấy typedefs như thế này, xin vui lòng không bắt đầu sử dụng cú pháp này. - Lundin
@ Lundin Tôi không đồng ý. Đặt tất cả chúng trên một dòng làm cho nó rõ ràng rằng bạn có ý định để tất cả chúng đề cập đến cùng một loại cơ sở. Theo định nghĩa. - Mr Lister
@MrLister Nếu bạn viết chúng ở mỗi dòng riêng biệt sau mỗi dòng khác, mỗi dòng sẽ bắt đầu bằng typedef some_type ... và bạn có một số dòng như thế, ý định của bạn rất rõ ràng và không có chỗ cho cú pháp cú pháp. Xa dễ đọc hơn. - Lundin
@ Lundin Nó có thể là một vấn đề của hương vị, vì vậy tôi không chắc chắn nếu chúng ta cần phải đi vào một cuộc thảo luận về điều này. - Mr Lister


Các câu trả lời:


Nó tuyên bố một số typedefs cùng một lúc, giống như bạn có thể khai báo một số biến cùng một lúc. Họ là tất cả các loại dựa trên int, nhưng một số được sửa đổ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

97
2018-02-27 07:30



Trong suốt nhiều 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 nó là cần thiết để tìm hiểu điều đó và tôi không bao giờ tìm thấy bất cứ điều gì về nó. +1 - John Odom
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 mà bạn không nên sử dụng. - Plutor


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

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

C ++ 11 7.1.3 Các typedef người chỉ định

A typedef-name không giới thiệu kiểu mới theo cách class khai báo (9.1) hoặc enum khai báo does.Example: after

typedef int MILES , * KLICKSP ;

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

MILES distance ;
extern KLICKSP metricp ;

tất cả đều là khai báo chính xác; loại khoảng cách là int của metricp là "con trỏ đến int. ”—Ví dụ


41
2018-02-27 07:26



Để hiểu biết của tôi câu trả lời là chính xác. Tại sao có một cuộc bỏ phiếu phủ định? - Dipto


Nếu bạn có cdecl lệnh, bạn có thể sử dụng nó để làm rõ 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 bạn không có cdecl, bạn sẽ có thể cài đặt nó theo cách thông thường (ví dụ: trên hệ thống kiểu Debian, sử dụng sudo apt-get install cdecl).


32
2018-02-27 07:32



nơi này cdecl lệnh đến từ đâu? - athos
@athos Từ sudo apt-get install cdecl - Amarghosh
oh vì vậy nó không dành cho Windows? - athos


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

Tôi đoán họ sử dụng typedef trong 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 phù hợp với nhận xét của Brian:

int(&name)(...) là một tham chiếu hàm gọi là 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 hàm trả về int tham 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 chứng).


0
2018-02-27 07:37



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 là tối nghĩa và không hữu ích lắm, nhưng chúng tồn tại trong C ++. - Brian
Chắc chắn nó là một chút phức tạp, nhưng thay thế là gì? Không sử dụng typedef? Bạn vẫn cần kiểu, nhưng không có typedef, bạn phải sử dụng rõ ràng cùng một kiểu hàm ở mọi nơi cần thiết, điều này khó hiểu gấp mười lần, và tất nhiên là có lỗi. Thay vì phải nhận được một typedef đúng, lập trình viên cần phải có được loại quyền ở nhiều nơi. - gnasher729
"nó được đề nghị" bởi ai? Typedefs cho các con trỏ hàm được sử dụng rất phổ biến trong nhiều API C để gọi lại và sử dụng typedef có nghĩa là hàm nhận con trỏ hàm vì tham số của nó dễ đọc hơn nhiều. Trừ khi bạn có thể sử dụng C ++ lambdas, hàm typedefs của con trỏ là kiểu mã hóa tốt hơn IMO hơn là sử dụng chúng trực tiếp nếu bạn triển khai ví dụ: API không đồng bộ. - uliwitness


typedef đang định nghĩa một kiểu mới để sử dụng trong mã của bạn, giống như một 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 và không phải là một đối tượng bên trong _MyBase.

:: là phạm vi của loại. Nó là loại giống như "là trong" vì vậy value_type "là trong" _MyBase. hoặc cũng có thể được cho là có 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


-7
2018-02-27 07:34



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 typedef (mà bạn đã giải thích) nhưng bị bối rối bởi cái phức tạp hơn (mà bạn thậm chí không chạm vào). - mirabilos