Chúng ta có thể xây dựng các thùng chứa với các khung nhìn trong C ++ 20 không?


10

Phạm vi đang đến với C ++ với phiên bản tiêu chuẩn C ++ 20.

Câu hỏi của tôi: Liệu chúng ta có thể xây dựng các thư viện thư viện tiêu chuẩn (hiện có) với bất kỳ phạm vi nào không? Và quan trọng hơn, với tầm nhìn phạm vi?

Ví dụ: sẽ thế này:

#include <vector>
#include <iostream>
#include <ranges>

int main() {
    auto sq = [](int x) { return x * x; };
    std::vector<int> vec { 3, 4, 5 };
    std::vector<int> squares { std::ranges::views::transform(vec, sq) };
    for(auto i : squares) { std::cout << i << ' '; }
    std::cout << std::endl;
}

là một chương trình hợp lệ mà in 9 16 25?

Điều này biên dịch với thư viện Range-v3 , cho những gì đáng giá.



Per StoryTeller: trùng lặp rõ ràng Tại sao thư viện Ranges sắp tới không hỗ trợ khởi tạo vùng chứa từ một phạm vi? Giáo sư lưu ý rằng độ phân giải lá phiếu có thể thay đổi câu trả lời!
Davis Herring

@DavisHerring Điều gì có thể thay đổi? P1206 không được xem xét cho 20 để bắt đầu và tôi không nghĩ có bất kỳ bình luận NB nào bị bỏ ngỏ ở đây? P1391 đã được thông qua mà không có nhà xây dựng phạm vi (mặc dù ví dụ sai lệch).
Barry

@Barry: LEWG đã chuyển tiếp nó trong Kona, nhưng tôi đoán tôi đã hiểu sai lưu lượng phản xạ gần đây về nó.
Davis Herring

@DavisHerring Ồ, tôi đã bỏ lỡ rằng nó đã được thảo luận hai lần - Tôi đã cuộn xuống cuộc thăm dò 4-7 và nghĩ rằng đó là điều đó.
Barry

Câu trả lời:


8

Câu hỏi của tôi: Liệu chúng ta có thể xây dựng các thư viện thư viện tiêu chuẩn (hiện có) với bất kỳ phạm vi nào không? Và quan trọng hơn, với tầm nhìn phạm vi?

Không. Thành phần thư viện tiêu chuẩn duy nhất có thể xây dựng từ một phạm vi tùy ý đáp ứng các tiêu chí chính xác là std::span<T>.

Hướng mà thư viện chuẩn có thể sẽ đi theo hướng mà phạm vi-v3 cũng sẽ hướng tới (lưu ý rằng ví dụ được liên kết từ phạm vi-v3 không biên dịch nhưng cảnh báo về chuyển đổi không dùng nữa) - sử dụng trình trợ giúp để thực hiện chuyển đổi cho bạn:

std::vector<int> squares =
    std::ranges::views::transform(vec, sq) | std::ranges::to<std::vector>;

Một trong những lý do để không đi theo hướng của các nhà xây dựng phạm vi có thể được nhìn thấy từ chính ví dụ bạn đang sử dụng:

std::vector<int> squares { std::ranges::views::transform(vec, sq) };

Xem xét sự khác biệt của tuyên bố đó từ hai:

std::vector v { std::ranges::views::transform(vec, sq) };
std::vector w ( std::ranges::views::transform(vec, sq) );

vsẽ nhất thiết phải là một vector<transform_view<...>>chứa một transform_view, trong khi wsẽ là một vector<int>.

Hơn nữa, việc thêm nhiều hơn, các hàm tạo container bị ràng buộc cẩn thận vào thư viện chuẩn sẽ không giúp ích gì cho các loại container của bên thứ ba - trong khi một cơ sở như ranges::tohoạt động hoàn toàn tốt trong mọi trường hợp.


Các báo cáo khởi tạo vw trông giống như tôi. Có lẽ bạn có nghĩa là tuyên bố wnhư một vector<int>. Nếu không, đây là câu trả lời chính xác.
Eric Niebler

5
@EricNiebler Chính xác :-) Chúng trông giống nhau. Chúng không giống nhau.
Barry

Vì vậy, chương trình của tôi biên dịch nhưng sẽ không làm những gì tôi nghĩ. Đồng ý.
einpoklum

1
Cảm ơn, CTAD ...
TC

Bạn có thể vui lòng giải thích tại sao vwkhác nhau? Nó có liên quan gì đến cách suy luận đối số của hàm tạo không?
Julian Schaub - litb
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.