std :: bỏ qua với các ràng buộc có cấu trúc?


82

Khúc dạo đầu:

std::tuple<int, int, int> f();
std::tuple<int, int, float, int> g();

C ++ 1z sẽ giới thiệu cú pháp cho các ràng buộc có cấu trúc giúp bạn có thể viết thay vì

int a, b, c;
std::tie(a, b, c) = f();

cái gì đó như

auto [a, b, c] = f();

Tuy nhiên, std::tiecũng được phép chỉ định std::ignorebỏ qua một số thành phần nhất định, ví dụ:

std::tie(a, b, std::ignore, c) = g();

Liệu có thể làm điều gì đó tương tự bằng cách sử dụng cú pháp liên kết có cấu trúc mới không? Nó sẽ hoạt động như thế nào?


2
Chỉ cần đặt một cái tên tùy ý ở đó.
n. 'đại từ' m.

1
@nm sẽ không tạo ra một tên tùy ý sao?
Piotr Skotnicki

1
@Piotr Không nhiều bản sao hơn với std::ignore, tôi nghĩ vậy. Vì chúng tôi đã đảm bảo tách bản sao, biến giả được khởi tạo; với std::tie, tạm thời ở rhs của nhiệm vụ std::ignoređược khởi tạo.
j6t

1
Có thể có một macro auto[IGNORE]tạo ra một tên duy nhất (ví dụ: với COUNTER hoặc LINE dành riêng cho trình biên dịch ). Nó sẽ là đủ có thể đọc được, và trong thực tế sẽ hoạt động như std::ignorecho std::tie.
KABoissonneault

2
@PiotrSkotnicki Không, bản sao duy nhất mà khai báo phân tách tạo ra là thứ đang được phân tách. Những thứ đang được khai báo hoặc là bí danh của các thành viên / phần tử của thứ đó hoặc tham chiếu liên kết với những gì gettrả về.
TC

Câu trả lời:


57

Đề xuất ràng buộc có cấu trúc chứa một phần dành riêng trả lời câu hỏi của bạn ( P0144R2 ):

3.8 Có nên có một cách để bỏ qua các thành phần một cách rõ ràng không?

Động cơ sẽ là tắt các cảnh báo của trình biên dịch về các tên không sử dụng. Chúng tôi nghĩ rằng câu trả lời nên là "chưa." Điều này không được thúc đẩy bởi các trường hợp sử dụng (tắt tiếng cảnh báo trình biên dịch là một động lực, nhưng nó không phải là trường hợp sử dụng cho mỗi trường hợp sử dụng) và tốt nhất là nên để cho đến khi chúng tôi có thể xem lại điều này trong bối cảnh đề xuất so khớp mẫu chung hơn, nơi điều này sẽ xảy ra như một trường hợp đặc biệt.

Đối xứng với std::tiesẽ đề xuất sử dụng một cái gì đó như std::ignore:

tuple<T1,T2,T3> f();

auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element

Tuy nhiên, điều này cảm thấy khó xử.

Dự đoán đối sánh mẫu trong ngôn ngữ có thể đề xuất một ký tự đại diện như _hoặc *, nhưng vì chúng tôi chưa có đối sánh mẫu nên còn quá sớm để chọn một cú pháp mà chúng tôi biết là sẽ tương thích. Đây là một tiện ích mở rộng thuần túy có thể chờ được xem xét với đối sánh mẫu.

Tuy nhiên, lưu ý rằng dự thảo làm việc của Tiêu chuẩn hiện đang được các Cơ quan Quốc gia (NB) có liên quan sửa đổi và có một bình luận của NB yêu cầu tính năng này ( P0488R0 , US100):

Các khai báo phân tách phải cung cấp cú pháp để loại bỏ một số giá trị được trả về, giống như cách std::tiesử dụng std::ignore.


6
Bây giờ đã quá muộn, nhưng tôi sẽ chỉ ra rằng một tính năng cảm thấy khó sử dụng và có thể sẽ được thay thế trong tương lai sẽ tốt hơn là không có khả năng sử dụng tính năng đó và điều này có vẻ không phải là loại điều sẽ khiến ủy ban tiêu chuẩn mong muốn có một cỗ máy thời gian vì không có cách giải thích hợp lý nào khác về std::ignorecác ràng buộc có cấu trúc.
Daniel H

9

Liệu có thể làm điều gì đó tương tự bằng cách sử dụng cú pháp liên kết có cấu trúc mới không?

Không. Bạn chỉ cần tạo một tên biến mà sau này sẽ không đề cập đến.


25
sẽ tạo ra cảnh báo biến không được sử dụng -Wunused-variable, bạn có thể sử dụng: [[maybe_unused]] auto [ a, b, dummy ] = std::tuple(1,"2",3f);nhưng điều đó có nghĩa là bất kỳ biến nào trong số đó có thể không được sử dụng, bạn sẽ không biết cái nào. không có giải pháp tốt cho trường hợp đó ngay bây giờ. hy vọng nó sẽ được cải thiện trong c ++ 20. lấy từ đây: stackoverflow.com/questions/41404001/…
serine

3
"không có giải pháp tốt cho trường hợp đó ngay bây giờ" : điều đó không hoàn toàn đúng: Bạn có thể đơn giản sử dụng (void)dummy;để loại bỏ cảnh báo biến không sử dụng mà không ảnh hưởng đến các biến khác.
andreee

16
@andreee: Sử dụng hết một câu lệnh chỉ để đưa ra một cảnh báo không phải là điều mà tôi gọi là "giải pháp tốt".
Nicol Bolas

"Sử dụng hết một tuyên bố chỉ để im lặng một cảnh báo ..." Chúng ta sắp hết phát biểu?
AndyJost

1
@AndyJost: Không, nhưng chúng tôi sắp hết dung lượng hiển thị trên màn hình. Việc dành nó, đặc biệt là không gian dọc quý giá, để làm im lặng cảnh báo là không hữu ích.
Nicol Bolas
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.