Чи зможемо ми сконструювати контейнери з видами в 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?

Це компілюється з бібліотекою ranges-v3 для того, що варто.



За StoryTeller: очевидний дублікат програми Чому майбутня бібліотека діапазонів не підтримує ініціалізацію контейнера з діапазону? — Але зауважте, що роздільна здатність голосування все ж може змінити відповідь!
Оселедець Девіса

@DavisHerring Що може змінитися? P1206 не вважався для початку 20, і я не думаю, що тут залишаються відкритими коментарі NB? P1391 прийнятий без конструктора діапазону (незважаючи на оманливий приклад).
Баррі

@Barry: LEWG так переслала його в Кону, але, мабуть, я неправильно трактувала трафік останніх рефлекторів про це.
Оселедець Девіса

@DavisHerring О, я пропустив, що це обговорювалося двічі - я прокрутився до опитування 4-7 і подумав, що це все.
Баррі

Відповіді:


8

Моє запитання: Чи зможемо ми побудувати (існуючі) стандартні бібліотечні контейнери з будь-яким діапазоном? І що ще важливіше, з видом діапазону?

Ні. Єдиний стандартний компонент бібліотеки, який можна сконструювати з довільного діапазону, який відповідає правильним критеріям std::span<T>.

Напрямок, до якого, ймовірно, піде стандартна бібліотека, є той, до якого також іде діапазон-v3 (зауважте, що пов'язаний приклад з range-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, тоді як wбуде a vector<int>.

Більше того, додавання більше, ретельно обмежених конструкторів контейнерів до стандартної бібліотеки все одно не допоможе стороннім типам контейнерів - в той час як об'єкт на зразок ranges::toпрацює чудово у всіх випадках.


Твердження ініціалізуються vі wвиглядають однаково для мене. Можливо, ви мали намір оголосити себе wяк vector<int>. В іншому випадку це правильна відповідь.
Ерік Ніблер

5
@EricNiebler Рівно :-) Вони виглядають однаково. Вони не однакові.
Баррі

Отже, моя програма компілює, але не буде робити те, що я думаю, що це робить. Добре.
einpoklum

1
Дякую, CTAD ...
TC

Чи можете ви пояснити , чому vі wрізні? Чи має це щось спільне з тим, як працює виведення аргументу шаблону конструктора?
Йоханнес Шауб - ліб
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.