No.
Единственное, что вы можете передать, это адаптеры диапазона — алгоритмы, которые принимают диапазон и производят диапазон. Алгоритмы, которые принимают диапазон и возвращают один объект (также известные как катаморфизмы), не поддерживают конвейер в диапазонах range-v3 или C++20.
Вы должны написать это так:
const double val = accumulate(data | transform(...));
Что касается того, почему accumulate
и подобные алгоритмы будут изо всех сил пытаться когда-либо быть |
-способными. Учтите, что мы хотим, чтобы algo(rng, x)
и rng | algo(x)
означали одно и то же. Кроме того, учтите, что «полный вызов» algo(rng, x)
может быть полностью ограничен (поскольку у вас есть вся информация), в то время как «частичный вызов» algo(x)
в основном должен быть полностью неограничен во всех, кроме редких случаях... в основном примерно принимая auto&&...
Проблема в том, что мы неизбежно сталкиваемся с неясностями, когда второй аргумент, x
, может также быть диапазоном. Как вы различаете, является ли намерение полным вызовом или частичным вызовом?
Вот пример использования string
:
accumulate("hello"s, ""s)
Это общий вызов, в котором используется двоичный оператор по умолчанию +
, представляющий собой конкатенацию строк. Это перебирает элементы диапазона char
s и добавляет их один за другим в исходную пустую строку. Это неэффективный, но правильный способ скопировать файл string
. Вы получите значение "hello"s
.
А как насчет его эквивалентной версии с трубой?
"hello"s | accumulate(""s)
Что означает правая сторона? Можно ли считать accumulate(""s)
полным вызовом? Да, оно может! 2-й аргумент по умолчанию будет char()
, а третий аргумент по умолчанию будет plus()
, это работает нормально, и поэтому значение accumulate(""s)
равно целому числу 0
, что делает все выражение неправильным, потому что нет operator|(string, int)
.
Как вы заставляете это работать с accumulate
?
person
Barry
schedule
02.12.2019