Phổ Biến 6/2024 # Khi Nào Dấu Ngoặc Đơn Có Tác Dụng, Ngoài Việc Ưu Tiên Toán Tử? # Top 7 Yêu Thích

TL; DR

Dấu ngoặc đơn thay đổi ý nghĩa của chương trình C ++ trong các ngữ cảnh sau:

ngăn chặn tra cứu tên phụ thuộc vào đối số

bật toán tử dấu phẩy trong ngữ cảnh danh sách

giải quyết sự mơ hồ của các phân đoạn khó chịu

suy ra tham chiếu trong decltypebiểu thức

ngăn chặn lỗi macro bộ xử lý trước

Ngăn tra cứu tên phụ thuộc vào đối số

Như được trình bày chi tiết trong Phụ lục A của Tiêu chuẩn, a post-fix expressioncó dạng (expression)là a primary expression, nhưng không phải id-expressionvà do đó không phải là unqualified-id. Điều này có nghĩa là tra cứu tên phụ thuộc đối số bị ngăn chặn trong các lệnh gọi hàm của biểu mẫu (fun)(arg)so với biểu mẫu thông thường fun(arg).

3.4.2 Tra cứu tên phụ thuộc vào đối số [basic.lookup.argdep]

1 Khi biểu thức hậu tố trong một lệnh gọi hàm (5.2.2) là một id không đủ tiêu chuẩn , các không gian tên khác không được xem xét trong quá trình tra cứu thông thường không đủ tiêu chuẩn (3.4.1) có thể được tìm kiếm và trong các không gian tên đó, hàm bạn của không gian tên phạm vi hoặc Có thể tìm thấy các khai báo mẫu hàm (11.3) không hiển thị. Những sửa đổi này đối với tìm kiếm phụ thuộc vào loại đối số (và đối với đối số mẫu mẫu, không gian tên của đối số mẫu). [ Thí dụ:

Bật toán tử dấu phẩy trong ngữ cảnh danh sách

Toán tử dấu phẩy có một ý nghĩa đặc biệt trong hầu hết các ngữ cảnh giống như danh sách (đối số hàm và mẫu, danh sách trình khởi tạo, v.v.). Dấu ngoặc đơn của biểu mẫu a, (b, c), dtrong các ngữ cảnh như vậy có thể cho phép toán tử dấu phẩy so với biểu mẫu thông thường a, b, c, d không áp dụng toán tử dấu phẩy.

5.18 Toán tử dấu phẩy [expr.comma]

2 Trong các ngữ cảnh mà dấu phẩy có ý nghĩa đặc biệt, [Ví dụ: trong danh sách các đối số cho các hàm (5.2.2) và danh sách các bộ khởi tạo (8.5) – ví dụ thêm] toán tử dấu phẩy như được mô tả trong Điều 5 chỉ có thể xuất hiện trong dấu ngoặc đơn. [ Thí dụ:

có ba đối số, đối số thứ hai có giá trị 5. -end ví dụ]

Giải quyết sự mơ hồ của các phân đoạn khó chịu

Khả năng tương thích ngược với C và cú pháp khai báo hàm phức tạp của nó có thể dẫn đến sự mơ hồ phân tích cú pháp đáng ngạc nhiên, được gọi là phân tích cú pháp khó chịu. Về cơ bản, bất kỳ thứ gì có thể được phân tích cú pháp như một khai báo sẽ được phân tích cú pháp thành một , mặc dù một phân tích cú pháp cạnh tranh cũng sẽ được áp dụng.

6.8 Giải quyết sự mơ hồ [stmt.ambig]

8.2 Giải quyết sự mơ hồ [dcl.ambig.res]

1 Sự không rõ ràng phát sinh do sự giống nhau giữa một kiểu hàm và một khai báo được đề cập trong 6.8 cũng có thể xảy ra trong ngữ cảnh của một khai báo . Trong bối cảnh đó, sự lựa chọn là giữa một khai báo hàm với một tập hợp các dấu ngoặc đơn dự phòng xung quanh tên tham số và một khai báo đối tượng với một kiểu hàm kiểu làm bộ khởi tạo. Cũng như đối với những điểm không rõ ràng được đề cập trong 6.8, giải pháp là xem xét bất kỳ cấu trúc nào có thể là một khai báo . [Lưu ý: Một khai báo có thể được phân định rõ ràng bằng kiểu ép kiểu phi chức năng, bằng dấu = để chỉ ra sự khởi tạo hoặc bằng cách xóa dấu ngoặc đơn thừa xung quanh tên tham số. -Gửi ghi chú] [Ví dụ:

Một ví dụ nổi tiếng về vấn đề này là Most Vexing Parse , một cái tên được Scott Meyers phổ biến trong Mục 6 của cuốn sách STL Hiệu quả của ông :

Đặt thêm dấu ngoặc đơn xung quanh đối số hàm đầu tiên (dấu ngoặc quanh đối số thứ hai là bất hợp pháp) sẽ giải quyết sự mơ hồ

C ++ 11 có cú pháp khởi tạo dấu ngoặc nhọn cho phép loại bỏ các vấn đề phân tích cú pháp như vậy trong nhiều ngữ cảnh.

Khấu trừ tham chiếu trong decltypebiểu thức

Ngược lại với autosuy luận kiểu, decltypecho phép suy ra tham chiếu (tham chiếu giá trị và giá trị). Các quy tắc phân biệt giữa decltype(e)và decltype((e)) biểu thức:

7.1.6.2 Bộ chỉ định loại đơn giản [dcl.type.simple]

4 Đối với một biểu thức e, kiểu được biểu thị bằngdecltype(e) được định nghĩa như sau:

– if elà một biểu thức id không có dấu ngoặc đơn hoặc quyền truy cập thành viên lớp không có dấu ngoặc đơn (5.2.5), decltype(e)là kiểu thực thể được đặt tên bởi e. Nếu không có thực thể như vậy, hoặc nếu e đặt tên cho một tập hợp các hàm quá tải, chương trình không được định hình;

– nếu không, decltype(e)là loại e.

Toán hạng của trình xác định kiểu khai báo là một toán hạng không được đánh giá (Điều 5). [ Thí dụ:

Trả về đầu tiên string, trả về thứ hai string &, là một tham chiếu đến biến cục bộ str.

sử dụng dấu ngoặc đơn xung quanh các tham số macro bên trong định nghĩa macro #define TIMES(A, B) (A) * (B);để tránh ưu tiên toán tử không mong muốn (ví dụ: trong TIMES(1 + 2, 2 + 1)đó kết quả là 9 nhưng sẽ mang lại 6 mà không có dấu ngoặc đơn xung quanh (A)và(B)

sử dụng dấu ngoặc đơn xung quanh một hàm để bảo vệ khỏi việc mở rộng macro trong các tiêu đề được bao gồm: (min)(a, b)(với tác dụng phụ không mong muốn là vô hiệu hóa ADL)