Trong ví dụ của Stroustrup, dấu hai chấm có nghĩa gì trong việc trả về 1: 2,?


163

Tôi không hiểu một cách sử dụng cụ thể của dấu hai chấm.

Tôi tìm thấy nó trong cuốn sách Ngôn ngữ lập trình C ++ của Bjarne Stroustrup, ấn bản thứ 4, phần 11.4.4 "Gọi và trả lại", trang 297:

void g(double y)
{
  [&]{ f(y); }                                               // return type is void
  auto z1 = [=](int x){ return x+y; }                        // return type is double
  auto z2 = [=,y]{ if (y) return 1; else return 2; }         // error: body too complicated
                                                             // for return type deduction
  auto z3 =[y]() { return 1 : 2; }                           // return type is int
  auto z4 = [=,y]()−>int { if (y) return 1; else return 2; } // OK: explicit return type
}

Dấu hai chấm khó hiểu xuất hiện trên dòng 7, trong tuyên bố return 1 : 2. Tôi không biết nó có thể là gì. Nó không phải là một nhãn hoặc nhà điều hành ternary.

Nó có vẻ như là một toán tử ternary có điều kiện mà không có thành viên đầu tiên (và không có ?), nhưng trong trường hợp đó tôi không hiểu làm thế nào nó có thể hoạt động mà không có điều kiện.


6
Đó là một lỗi biên dịch trên đầu của tôi (gcc và clang). Cộng với tất cả những dòng đó cần dấu chấm phẩy, nhưng vẫn có lỗi.
Cruz Jean

216
Người điều hành Lưu ý: Vui lòng suy nghĩ thật kỹ trước khi bỏ phiếu để đóng câu hỏi này dưới dạng câu hỏi "lỗi đánh máy". Vâng, vấn đề là một lỗi đánh máy, nhưng nó không phải là một lỗi đánh máy mà người hỏi đã thực hiện. Thay vào đó, nó được tìm thấy trong một cuốn sách được xuất bản. Điều đó có nghĩa là câu hỏi này và câu trả lời của nó có thể hữu ích cho những người khác trong tương lai, đây là một chỉ số phản biện mạnh mẽ để đóng nó dưới dạng một lỗi đánh máy. (CẬP NHẬT: Chủ đề này hiện đang được thảo luận trên Meta ; xin vui lòng cân nhắc ở đó.)
Cody Grey

3
Có lẽ câu trả lời tốt nhất sẽ là: Cố gắng biên dịch mã; nếu nó không biên dịch, đó là một dấu hiệu tốt cho thấy đó là một lỗi đánh máy.
jrw32982 hỗ trợ Monica

Tôi có thể nghĩ ra một số ví dụ ngoài đỉnh đầu không biên dịch (hoặc thậm chí gây ra lỗi trình biên dịch nội bộ) trên một trình biên dịch, nhưng được chấp nhận mà không gặp sự cố nào trên một trình biên dịch khác
J. Antonio Perez

1
@ John Tôi chỉ thử một số biểu thức gấp với MSVC và chúng không được biên dịch. Vì vậy, rõ ràng toàn bộ chương tôi vừa đọc phải là một lỗi đánh máy? ;) Trình biên dịch C ++ không thể biên dịch mã C ++ hợp lệ mọi lúc, xuất phát từ ngôn ngữ phức tạp một cách vô lý.
Voo

Câu trả lời:


205

Đó là một lỗi đánh máy trong cuốn sách. Nhìn vào Errata cho các bản in thứ 2 và thứ 3 của Ngôn ngữ lập trình C ++ . Ví dụ phải như dưới đây:

auto z3 =[y]() { return (y) ? 1 : 2; }

11
Tại sao (y)và không chỉ y?
Người trợ giúp nhỏ

7
@LittleHelper Có lẽ đó là một cách thực hành tốt nhất hoặc một cái gì đó, tôi luôn thấy nó được viết như thế. Có lẽ để tránh nhầm lẫn với những so sánh phức tạp hơn ...
Chương trình Redwolf

28
Cá nhân, tôi thường sử dụng (cond) ? a : bcho rõ ràng - nó giúp tôi tránh hiểu sai ví dụ như báo cáo kết quả foo = x > y ? a : bnhư foo = x ...khi lướt qua mã.
dùng1686

8
@LittleHelper Nó không thực sự cần thiết ở đó. Tuy nhiên, trong một macro giống như hàm, cách tốt nhất là đặt dấu ngoặc quanh các đối số nơi chúng được sử dụng, vì nếu không, việc mở rộng các đối số có thể tạo ra hành vi không mong muốn. Xem xét một macro giống như hàm để nhân đôi giá trị "foo (x) x * 2" trong đó bạn gọi nó bằng "foo (2 + 3)". Kết quả sẽ là 2+ (3 * 2) vì đối số được mở rộng nguyên trạng và các quy tắc ưu tiên tiếp quản. Nếu macro của bạn là "foo (x) (x) * 2" thì bạn sẽ nhận được chính xác (2 + 3) * 2. Có thể Stroustrup có thói quen sử dụng phong cách đó ở mọi nơi để mã hóa an toàn.
Graham

2
@Graham Rất khó xảy ra. Stroustrup về cơ bản không ghi các macro chức năng (các hàm nội tuyến C ++ tốt hơn). Nhiều khả năng là toán tử ternary có các quy tắc ưu tiên hơi phức tạp, vì vậy tốt nhất là thường xuyên làm rõ các ưu tiên với parens.
Martin Bonner hỗ trợ Monica

19

Trông tôi như một lỗi đánh máy đơn giản. Có lẽ nên:

auto z3 =[y]() { return y ? 1 : 2; }

Lưu ý rằng vì lambda không lấy bất kỳ tham số nào, nên các parens là tùy chọn. Bạn có thể sử dụng cái này thay thế, nếu bạn thích:

auto z3 =[y] { return y ? 1 : 2; }

11

return 1 : 2; là một lỗi cú pháp, nó không phải là mã hợp lệ.

Một tuyên bố chính xác sẽ giống như return (y) ? 1 : 2;thay vào đó.

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.