2014-12-15 13 views
8

Tôi muốn làm điều này:Làm cách nào để tạo bí danh cho con trỏ chức năng noexcept?

using function_type = void (*)(void*)noexcept; 

Nhưng tôi nhận được một lỗi "thông số kỹ thuật ngoại lệ không được phép vào loại bí danh." (clang trong phiên bản 6.1 của Xcode)

Có cách giải quyết nào để tạo bí danh với trình chỉ định không nhận dạng không?

Tôi đang tìm một thứ hoạt động như được xác định bởi ngôn ngữ (không phải là phần mở rộng) cho các khả năng đa nền tảng.

+1

g ++ biên dịch tốt. Có lẽ nó chỉ bỏ qua các specifier ... – DarioP

+1

GCC không phải là tiêu chuẩn tuân thủ ở đây. Clang là chính xác. – Columbo

+1

Hm, đó là một lỗi gcc lạ. Ut không chấp nhận typedef nhưng chấp nhận 'using'. –

Trả lời

9

Tiêu chuẩn rõ ràng cấm đặc tả ngoại lệ xuất hiện trong một tuyên bố typedef hoặc bí danh. Nhưng nó cũng nói rằng trình định danh ngoại lệ có thể xuất hiện trong một kiểu con trỏ hàm.

§15.4/2[except.spec]

An exception-specification shall appear only on a function declarator for a function type, pointer to function type, reference to function type, or pointer to member function type that is the top-level type of a declaration or definition, or on such a type appearing as a parameter or return type in a function declarator. An exception-specification shall not appear in a typedef declaration or alias-declaration.

Và nếu một con trỏ đến chức năng không có một đặc điểm kỹ thuật ngoại lệ, sau đó con trỏ hàm phải lúc nào cũng được chỉ định một loại chức năng mà có một đặc tả ngoại lệ tương thích.

§15.4/5

... A similar restriction applies to assignment to and initialization of pointers to functions, pointers to member functions, and references to functions: the target entity shall allow at least the exceptions allowed by the source value in the assignment or initialization. ...

Sử dụng hai này, bạn có thể nhận được các đặc điểm kỹ thuật noexcept vào kiểu con trỏ hàm trong một thời trang vòng xoay.

void (*foo_ptr)(void *) noexcept = nullptr; 
using function_type = decltype(foo_ptr); 

Bây giờ, bạn không thể chỉ định hàm không có thông số noexcept(true) cho con trỏ chức năng loại function_type. clang will fail to compile mã với lỗi

error: target exception specification is not superset of source

+1

Bất kỳ ý tưởng nào về lý do cho hạn chế này là gì? – kec

+0

Tôi không nghĩ rằng §15.4/4 giao dịch với nhiệm vụ hoặc khởi tạo. Bạn có thể muốn đoạn thứ hai của §15.4/5. –

+0

@kec Đoán của tôi là tránh có đặc tả ngoại lệ như một phần của loại hàm. – Praetorian

3

Một thay thế cho câu trả lời thuộc về pháp quan, mà không liên quan đến khai báo một biến:

void unused_function(void*)noexcept; 
using function_type = decltype(&unused_function); 

Các unused_function được khai báo, nhưng không xác định.

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