Tôi sử dụng typedef cho hầu hết mọi thứ, kể cả hàm. Trong vài tuần qua, tôi đã bắt đầu mã C++ của chúng tôi để phù hợp nhất có thể với tiêu chuẩn ISO C++ 11, sử dụng tài liệu dự thảo cuối cùng (N3242) làm hướng dẫn.Nhiều khai báo hàm C++ với tham số mặc định
Như chúng ta đã biết, thỉnh thoảng có nhiều khai báo leo vào mã của chúng tôi thông qua các extern xuất hiện trong nhiều tệp hoặc typedef được lặp lại. Theo đoạn trích này từ phần 7.1.3, trang 145 của tài liệu trên, điều này sẽ vô hại:
3. In a given non-class scope, a typedef specifier can be used to redefine the name of any type declared in that scope to refer to the type to which it already refers.
[ Example:
typedef struct s { /* ... */ } s; typedef int I; typedef int I; typedef I I;
— end example ]
Vì vậy, tôi đã viết một chương trình để kiểm tra điều này. Ở dạng đơn giản nhất của nó:
typedef int (fcntype)(int, int);
extern fcntype fcn1;
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2, 3); }
Biên soạn sử dụng gcc với
-Wfatal-errors -Wswitch-default -Wswitch-enum -Wunused-parameter -Wfloat-equal -Wundef -c -Wstrict-null-sentinel -std=c++0x -pedantic -Wall -Wextra
có, tất nhiên, không có vấn đề. Hãy khai thác hàm bị từ chối:
typedef int (fcntype)(int, int);
extern fcntype fcn1;
extern fcntype fcn1; // woops. probably from an #include ...
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2, 3); }
Theo tiêu chuẩn dự đoán, không có vấn đề gì. Hãy thực hiện thay đổi khác với bản gốc:
typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2); } // use the default param
Một lần nữa, không có vấn đề gì. vấn đề này được đưa ra về khi chúng ta có cả decl trùng lặp và các tham số defaulted như thế này:
typedef int (fcntype)(int, int=0); // default param.
extern fcntype fcn1;
extern fcntype fcn1; // FYI this is line 3 in the error message below.
int fcn1(int x, int y) { return x + y; }
int main(int argc, char ** argv) { return fcn1(2); } // use the default param
Và gcc phàn nàn với
decltest.cpp:3: error: default argument given for parameter 2 of ‘int fcn1(int, int)’
Tất nhiên, tôi đang dọn dẹp mã cách nó phải được làm sạch, đó là để nói rằng tôi đang corralling các decls thành một, tổ chức tốt hơn tập tin. Nhưng đây có phải là một lỗi trong trình biên dịch hoặc một sự hiểu lầm của tôi về những gì một tham số mặc định "là"?
Ngoài ra, chú thích cuối trang 101 (trên cùng một trang): "Điều này có nghĩa là đối số mặc định không thể xuất hiện, ví dụ, trong khai báo con trỏ tới hàm, tham chiếu đến hàm hoặc khai báo typedef." Vì vậy, tôi nghĩ rằng 'typedef int (fcntype) (int, int = 0);' nên tự nó đã không biên dịch. Hay tôi đang thiếu một cái gì đó? – Sven
Ah, vâng. Cảm ơn bạn đặc biệt cho các tài liệu tham khảo trong tiêu chuẩn. Tôi đã nhấn mạnh nó. Thật thú vị khi những thứ này trỗi dậy trên bạn, đó là một lý lẽ tốt để đi qua mã một lần trong một thời gian để dọn dẹp mọi thứ. –