2017-06-26 19 views
6

std::is_function chuyên với nhiều loại có chữ ký tương tự như:Loại int (int) & hoặc int (int) const &?

int(int) & 

thấy ở đây: std::is_function

Nhưng điều này không phải là một con trỏ đến một phương pháp thành viên, trong đó chữ ký có thể là:

int(T::*)(int) & 

Nó cũng không thể tham chiếu đến hàm:

int (&)(int) 

Vậy chữ ký lạ này là gì?

Trả lời

13

Đó là loại chức năng chỉ tồn tại trong hệ thống kiểu. Nó không bao giờ có thể được tạo ra.

Nhưng điều này không phải là một con trỏ đến một phương pháp thành viên, trong đó chữ ký có thể là:

int(T::*)(int) & 

Đó là này, mà không có con trỏ. Hệ thống kiểu cho phép bạn mô tả đó là một kiểu.

#include <type_traits> 

struct T { }; 
using A = int(int) &; 
using B = A T::*; 
using C = int(T::*)(int) &; 

static_assert(std::is_same_v<B, C>); 

@ T.C. đề cập đến PR0172R0, trong đó thảo luận về sự hiện diện của các loại này gây ra vấn đề cho người viết thư viện và gợi ý một số tùy chọn có thể làm giảm những vấn đề đó. Một trong các tùy chọn là loại bỏ hoàn toàn chúng, những người khác sẽ giảm tác động của chúng. Tùy thuộc vào cách này đi, câu trả lời này có thể hoặc có thể không chính xác cho các phiên bản tương lai của C + +.

+3

Tôi muốn liên kết đến tóm tắt tốt đẹp trong [P0172R0] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0172r0.html). –

+0

@ T.C. Cảm ơn, đã thêm một đề cập. – hvd

+3

Tôi tin rằng bạn cũng có thể sử dụng A = int (int) &; struct Bob {A foo; }; '. – Yakk

6

Trên trang tài liệu bạn liên kết đến, bạn sẽ thấy nhận xét này:

// specialization for function types that have ref-qualifiers 

trên danh sách các ví dụ bạn tham khảo đến từ.

Đó là các chức năng có bộ kiểm tra lại, bạn có thể đọc thêm về here.

Tóm lại, chúng tương tự như const chức năng đủ điều kiện. Dưới đây là ví dụ:

struct foo 
{ 
    void bar() & { std::cout << "this is an lvalue instance of foo" << "\n"; } 
    void bar() && { std::cout << "this is an rvalue instance of foo" << "\n"; } 
}; 

int main(int argc, char* argv[]) 
{ 
    foo f{}; 
    f.bar();   // prints "this is an lvalue instance of foo" 
    std::move(f).bar(); // prints "this is an rvalue instance of foo" 

    return 0; 
} 

Tôi không thể nghĩ về trường hợp sử dụng tuyệt vời cho tính năng này nhưng có thể sử dụng.

+1

[Ở đây] (https://github.com/dropbox/nn/blob/master/nn.hpp#L83) là một số ví dụ sử dụng;) –

5

Kể từ đầu lần (đề cập đến tiêu chuẩn ++ C đầu tiên), bạn có thể tuyên bố như vậy "lạ" các loại chức năng như, ví dụ

typedef int F() const; 

Mặc dù thực tế rằng việc kê khai trên không ngay lập tức liên quan đến bất kỳ lớp học , các dấu chấm câu const trong trường hợp này chỉ có thể phục vụ như là const-qualification của một hàm thành viên lớp không tĩnh. Điều này hạn chế việc sử dụng tên typedef ở trên để khai báo thành viên lớp. Ví dụ: người dùng có thể sử dụng số điện thoại như sau

struct S { 
    F foo;    // Declares an `int S::foo() const` member function 
}; 

int S::foo() const { // Defines it 
    return 42; 
} 

F S::*p = &S::foo; // Declares 'p' as `int (S::*)() const` pointer 

Lưu ý rằng, tuy nhiên, đây là một tính năng C++ cổ điển được viết bằng ngôn ngữ trong một thời gian dài.

Những gì bạn có trong ví dụ của bạn có hiệu quả giống nhau, nhưng với C++ 11 ref-qualifier thay cho vòng loại const.

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