toán tử mũi tên (->) trong tiêu đề hàm


127

Tôi đã xem qua đoạn mã sau:

template <typename T, typename T1> auto compose(T a, T1 b) -> decltype(a + b) {
   return a+b;
}

Có một điều tôi không thể hiểu:

Tôi có thể tìm ra toán tử mũi tên ( ->) nghĩa là gì trong tiêu đề hàm? Tôi đoán hoàn toàn hợp lý, rằng ->toán tử xác định một loại, autosẽ được suy ra, nhưng tôi muốn nói thẳng điều này. Tôi không thể tìm thấy bất kỳ thông tin.


2
Đây là một phần của cú pháp kiểu trả về. Xem stackoverflow.com/a/4113390/962089
chris

2
Nó không phải là một toán tử mà là một phần của cú pháp.
texasbruce

1
Trong câu trả lời cho "tôi có thể đọc ở đâu?", Thông số C ++ có thẩm quyền nhất. Thiếu tiền hoặc mong muốn chi tiêu $$, dự thảo làm việc cuối cùng thường đủ gần và không mất phí. Các thông số kỹ thuật này có tính công nghệ cao, vì vậy thiếu quen thuộc với việc đọc thông số kỹ thuật ISO, hãy thử cplusplus.com hoặc cppreference.com hoặc các trang web khác không có thẩm quyền, nhưng thường rất chính xác. Lưu ý: loại trả về theo sau có thể được bỏ qua bắt đầu bằng C ++ 14.
Les

Câu trả lời:


205

Trong C ++ 11, có hai cú pháp để khai báo hàm:

     khai báo đối số định danh kiểu trả về ( ... )

    auto ( khai báo đối số định danh ... ) -> return_type

Chúng là tương đương. Bây giờ khi chúng tương đương nhau, tại sao bạn lại muốn sử dụng cái sau? Chà, C ++ 11 đã giới thiệu điều hay ho này decltypecho phép bạn mô tả loại biểu thức. Vì vậy, bạn có thể muốn lấy ra kiểu trả về từ các kiểu đối số. Vì vậy, bạn hãy thử:

template <typename T1, typename T2>
decltype(a + b) compose(T1 a, T2 b);

và trình biên dịch sẽ cho bạn biết rằng nó không biết những gì abtrong decltypeđối số. Đó là bởi vì chúng chỉ được khai báo bởi danh sách đối số.

Bạn có thể dễ dàng giải quyết vấn đề bằng cách sử dụng declvalvà các tham số mẫu đã được khai báo. Giống:

template <typename T1, typename T2>
decltype(std::declval<T1>() + std::declval<T2>())
compose(T1 a, T2 b);

ngoại trừ bây giờ nó thực sự dài dòng. Vì vậy, cú pháp khai báo thay thế đã được đề xuất và thực hiện và bây giờ bạn có thể viết

template <typename T1, typename T2>
auto compose(T1 a, T2 b) -> decltype(a + b);

và nó ít dài dòng hơn và các quy tắc phạm vi không cần phải thay đổi.


Cập nhật C ++ 14: C ++ 14 cũng chỉ cho phép

    auto khai báo đối số định danh ( ... )

miễn là hàm được xác định đầy đủ trước khi sử dụng và tất cả các returncâu lệnh đều suy ra cùng loại. Các ->cú pháp vẫn còn hữu ích cho các chức năng công cộng (công bố trong tiêu đề) nếu bạn muốn ẩn cơ thể trong tập tin nguồn. Một số thứ rõ ràng không thể được thực hiện với các mẫu, nhưng có một số loại cụ thể (thường được bắt nguồn qua siêu lập trình mẫu) rất khó để viết khác.


2
trả lời rất tốt, gọn gàng và nhiều thông tin @Jan Hudec. Nhảy lên. Có cái gì đó thay đổi C++14khi tôi sử dụng autođể returngõ trong chức năng như vậy mà không cần -> decltype(a + b)phần. Bây giờ nó có dư thừa không hoặc nó có các trường hợp khác mà nó vẫn nên được sử dụng không? hoặc nó là một phần mở rộng cụ thể của trình biên dịch?
Shadi

1
@Shadi, C ++ 14 bao gồm N3638 , cho phép khấu trừ kiểu trả về được khai báo là auto, không có ->ký hiệu, miễn là hàm được xác định đầy đủ trước khi sử dụng và tất cả các returncâu lệnh đều suy ra cùng loại. Các ->ký hiệu vẫn còn hữu ích nếu bạn muốn sử dụng khấu trừ cho public function trong khi che giấu cơ thể trong tập tin nguồn.
Jan Hudec

23

Trong tiếng Anh đơn giản, nó nói rằng loại trả về là loại suy ra của tổng ab.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.