เราจะสามารถสร้างคอนเทนเนอร์ด้วยมุมมองใน C ++ 20 ได้หรือไม่?


10

ช่วงกำลังมาถึง C ++ ด้วยเวอร์ชันมาตรฐาน C ++ 20

คำถามของฉัน: เราจะสามารถสร้างคอนเทนเนอร์ไลบรารีมาตรฐาน (ปัจจุบัน) กับช่วงใด ๆ ได้หรือไม่ และที่สำคัญยิ่งกว่าด้วยมุมมองระยะไกล?

ตัวอย่างเช่นจะ:

#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;
}

เป็นโปรแกรมที่ถูกต้องซึ่งพิมพ์9 16 25?

สิ่งนี้จะรวบรวมกับไลบรารี range-v3สำหรับสิ่งที่คุ้มค่า



ต่อ StoryTeller: ซ้ำกันอย่างชัดเจนว่าทำไมไลบรารี Ranges ที่กำลังจะมาถึงไม่สนับสนุนการเริ่มต้นคอนเทนเนอร์จากช่วง? - แต่ทราบว่าความละเอียดของบัตรเลือกตั้งอาจเปลี่ยนคำตอบ!
Davis Herring

@DavisHerring สิ่งที่สามารถเปลี่ยนแปลงได้? P1206ไม่ได้รับการพิจารณาสำหรับการเริ่มต้นด้วย 20 และฉันไม่คิดว่าจะมีความคิดเห็น NB ใด ๆ ที่เหลืออยู่ที่นี่เปิด? P1391ถูกนำไปใช้โดยไม่มีตัวสร้างช่วง (แม้จะมีตัวอย่างที่ทำให้เข้าใจผิด)
Barry

@Barry: LEWG ส่งต่อไปที่ Kona แต่ฉันคิดว่าฉันตีความการจราจรของตัวสะท้อนแสงผิด ๆ เกี่ยวกับเรื่องนี้
Davis Herring

@DavisHerring โอ้ฉันคิดถึงสิ่งที่พูดถึงสองครั้ง - ฉันเลื่อนลงไปที่โพล 4-7 และคิดว่าเป็นแบบนั้น
Barry

คำตอบ:


8

คำถามของฉัน: เราจะสามารถสร้างคอนเทนเนอร์ไลบรารีมาตรฐาน (ปัจจุบัน) กับช่วงใด ๆ ได้หรือไม่ และที่สำคัญยิ่งกว่าด้วยมุมมองระยะไกล?

เลขที่องค์ประกอบห้องสมุดมาตรฐานเดียวที่เป็น constructible std::span<T>จากช่วงที่พลที่ตรงตามเกณฑ์ที่ถูกต้องคือ

ทิศทางห้องสมุดมาตรฐานมีแนวโน้มที่จะไปกับเป็นหนึ่งที่ช่วง v3 ยังเป็นไปต่อ (หมายเหตุว่าตัวอย่างที่เชื่อมโยงจากช่วง v3 จะรวบรวม แต่เตือนบนแปลงเลิกใช้แล้ว) - การใช้ผู้ช่วยที่จะทำแปลงสำหรับคุณ:

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

หนึ่งในเหตุผลที่ไม่เห็นทิศทางของตัวสร้างช่วงนั้นสามารถดูได้จากตัวอย่างที่คุณใช้:

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

พิจารณาว่าการประกาศนั้นแตกต่างจากสองสิ่งนี้อย่างไร:

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

vจำเป็นต้องจะเป็นvector<transform_view<...>>ที่มีเพียงหนึ่งเดียวtransform_viewในขณะที่จะเป็นwvector<int>

ยิ่งไปกว่านั้นการเพิ่มตัวสร้างคอนเทนเนอร์ที่ จำกัด มากขึ้นอย่างระมัดระวังในไลบรารีมาตรฐานจะไม่ช่วยประเภทคอนเทนเนอร์ของบุคคลที่สามอยู่ดีในขณะที่สิ่งอำนวยความสะดวกเช่นนี้ranges::toทำงานได้ดีอย่างสมบูรณ์ในทุกกรณี


คำสั่งเริ่มต้นvและwมีลักษณะเหมือนกันกับฉัน บางทีคุณอาจจะหมายถึงการประกาศเป็นw vector<int>มิฉะนั้นนี่คือคำตอบที่ถูกต้อง
Eric Niebler

5
@EricNiebler ตรง :-) พวกมันหน้าตาเหมือนกัน พวกเขาไม่เหมือนกัน
Barry

ดังนั้นโปรแกรมของฉันจะคอมไพล์ แต่จะไม่ทำสิ่งที่ฉันคิด ตกลง.
einpoklum

1
ขอบคุณ CTAD ...
TC

คุณช่วยอธิบายสาเหตุvและwความแตกต่างได้อย่างไร มันมีบางอย่างเกี่ยวกับวิธีการหักอาร์กิวเมนต์ของตัวสร้างเทมเพลตหรือไม่
Johannes Schaub - litb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.