Как я могу получить копируемый тип значения из Transform_view >?C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Как я могу получить копируемый тип значения из Transform_view >?

Сообщение Anonymous »

tl; dr < /h4>
Учитывая этот код: < /p>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

inline constexpr auto make_optional = [](auto&& x){
return std::make_optional(std::forward(x));
};

int main() {
std::vector const v1{3};
auto w1 = v1 | std::views::enumerate
| std::ranges::to() // THIS
;
using W1 = std::ranges::range_value_t;
W1 x1{1,2};
x1 = x1;

std::vector const v2{3};
auto w2 = v2 | ranges::views::enumerate
| ranges::to_vector // THIS
;
using W2 = ranges::range_value_t;
W2 x2{1,2};
x2 = x2;
}

Могу ли я изменить способ w1 /W2 вычисляются из трубопроводов, передаваемых в Decktype таким образом, чтобы я мог удалить две строки, помеченные // этим и все еще составляют две игрушечные самооценки? Если так, как?template
auto work1(Range r) {
Elem e;
e = *r.begin();
auto s = ranges::size(r);
return fun(s, e); // doesn't really matter, it just means e and s are needed
}

Эта функция всегда использовалась с Just std :: vector или Transform_view на нем, например. std::vector const vo{3};
work1(vo);

std::vector const v{3};
work1(v | ranges::views::transform(make_optional)); //¹

Недавно я осознал еще одну использование, которая влечет за собой передачу в work1 представление, которое перечислено d перед преобразованием (Make_optional) ed:

std::vector const v{3};
work1(v | ranges::views::enumerate
| ranges::views::transform(make_optional));

Это не может компилироваться по двум причинам:

Очевидно, что range-v3 перечисление не возвращает size_range с учетом ввода sized_range , а C ++ 20 не имеет перечисления во всех; Я исправил это, определив свой собственный перечисление _ , что zip s диапазон с верхней границей йота :
inline constexpr auto enumerate_ = [](auto&& r){
auto const s = ranges::size(r);
return ranges::views::zip(ranges::views::iota(0, static_cast(s)),
std::forward(r));
};
< /code>
< /li>
Исправлена это (или предполагаю, что у меня был C ++ 23), строка
e = *r.begin();
< /code>
не снимается, потому что
// C++17/20 + Range-v3
Object of type 'std::optional' cannot be assigned because its copy assignment operator is implicitly deleted
// C++23
Object of type 'std::optional' cannot be assigned because its copy assignment operator is implicitly deleted
< /code>
< /li>
< /ol>
Я понимаю сообщение об ошибке, минимальное воспроизведение для того, чтобы оно было так просто < /p>
using Foo = std::optional;
Foo f;
f = f; // same error as above

Тем не менее, просмотр перечисленного (т.е. если я не преобразую (make_optional) ), вычисляет elem == std :: tuple , тогда как Transform view Computes Elem == std :: Необходимо ; но когда они складываются вместе, тогда я получаю это std :: Необязательно , который, как очевидно, нельзя скопировать. std :: ranges :: to () Если бы у меня был C ++ 23, как я недавно узнал):
auto w = v | ranges::views::enumerate
| ranges::to_vector;
work1(w | ranges::views::transform(make_optional)); // ok

Но что, если я хочу избежать этого, и передать представление?std::optional
< /code>
в < /p>
std::optional
< /code>
(или < /p>
std::optional
< /code>
to < /p>
std::optional
< /code>
В сценарии C ++ 23). < /p>
Вот код, с которым я экспериментировал.inline constexpr auto make_optional = [](auto&& x){
return std::make_optional(std::forward(x));
};


Подробнее здесь: https://stackoverflow.com/questions/797 ... erate-view
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»