2014-10-02 15 views
45

Tiếp theo từ câu trả lời của tôi để this question, trong cả hai C++ 11 và C++ 14:Đặc điểm kỹ thuật của `bsearch` trong C++ 11 & C++ 14 có bị lỗi không?

[C++11, C++14: 25.5/2]: Nội dung cũng giống như các thư viện tiêu đề chuẩn C <stdlib.h> với các ngoại lệ sau:

[C++11, C++14: 25.5/3]: chức năng chữ ký:

bsearch(const void *, const void *, size_t, size_t, 
     int (*)(const void *, const void *)); 

được thay thế bằng hai tờ khai:

extern "C" void *bsearch(const void *key, const void *base, 
         size_t nmemb, size_t size, 
         int (*compar)(const void *, const void *)); 

extern "C++" void *bsearch(const void *key, const void *base, 
          size_t nmemb, size_t size, 
          int (*compar)(const void *, const void *)); 

cả hai đều có hành vi tương tự như khai báo ban đầu.

Tuy nhiên,

[C++11, C++14: 7.5/5]: Nếu hai tờ khai tuyên bố chức năng có cùng tên và tham số kiểu-list (8.3.5) phải là thành viên của không gian tên tương tự hoặc kê khai đối tượng có cùng tên với là thành viên của cùng một không gian tên và các khai báo cung cấp cho các tên các liên kết ngôn ngữ khác nhau, chương trình không đúng định dạng; không cần chẩn đoán nếu các khai báo xuất hiện ở các đơn vị dịch khác nhau. [..]

Đây có phải là lỗi không?

+0

Câu trả lời khớp trên hai hàm đó có cùng đối số hay không. Nếu liên kết là một phần của loại, 'so sánh' có một loại khác nhau trong cả hai ví dụ ... mặc dù nếu có, tôi muốn một số cách dễ dàng để khai báo nó cho các loại, và tôi không nhận thức được bất kỳ. – Deduplicator

+0

@Deduplicator Trong tiêu chuẩn C++, bạn sẽ có thể sử dụng bí danh mẫu. 'template sử dụng CxxFunc = R (T ...); extern "C" {template sử dụng CFunc = R (T ...); } '. Khai báo 'so sánh' dưới dạng' CFunc 'và' CxxFunc <...> '.Hầu hết các triển khai đều từ chối nó bởi vì chúng không cho phép các khuôn mẫu trong các khối 'extern" C "', nhưng nó hoàn toàn hợp lệ. Sự hạn chế là một khuôn mẫu không thể có liên kết 'extern" C "', không phải là một khuôn mẫu không thể xuất hiện trong một khối 'extern" C "'. Một bí danh mẫu không có liên kết ngôn ngữ, vì vậy nó ổn. – hvd

+1

Cũng giống như vậy trong C++ 98 25.4/3 (và 25.4/4 cho 'qsort') – Cubbi

Trả lời

49

Nhưng danh sách loại thông số không giống nhau. Trong một, compar là một con trỏ trỏ đến một hàm có liên kết ngôn ngữ "C", trong một cái khác, nó là một con trỏ trỏ đến một hàm có liên kết ngôn ngữ "C++".

C++ 11, 7,5 quy định cụ thể:

1 ... Có hai loại chức năng với ngôn ngữ khác nhau mối liên kết nhiều loại khác nhau ngay cả khi họ là khác giống hệt nhau.

4 Trong một mối liên kết đặc điểm kỹ thuật , các mối liên hệ ngôn ngữ cụ thể áp dụng cho các chức năng loại tất cả declarators hàm, tên hàm với mối liên hệ bên ngoài, và tên biến với bên ngoài liên kết tuyên bố trong liên kết-đặc điểm kỹ thuật . [Ví dụ:

extern "C" void f1(void(*pf)(int)); 
// the name f1 and its function type have C language 
// linkage; pf is a pointer to a C function 

Các mâu thuẫn dường như giữa 7,5/1 và 7,5/5 được giải quyết khi nhận ra rằng 1 cuộc đàm phán về chức năng loại, trong khi 5 địa chỉ hoạt động tên.

+0

Có cách nào dễ dàng để khai báo rằng fp đầu tiên có C++ và liên kết C thứ hai, cho hàm có hai hàm con trỏ? – Deduplicator

+0

@Deduplicator Sử dụng 'typedef' cho tham số khác với tham số ngôn ngữ của hàm chứa. – Angew

+4

Dường như không phải clang ++ hay g ++ coi chúng là khác nhau. http://coliru.stacked-crooked.com/a/ceb69c605e32832d – Deduplicator

Các vấn đề liên quan