Почему Op, который захватывает rvalue из std :: istringstream по значению, не соответствует концепции Accumulateable? - PullRequest
0 голосов
/ 24 апреля 2018

Это не скомпилируется:

auto acc_func = [iss{std::istringstream{}}](int acc, std::string &str) mutable {
    iss.str(str);
    int sz;
    iss >> sz;
    iss.clear();
    return acc + sz;

};
ranges::getlines_range lazy_lines = ranges::getlines(std::cin);
auto rng = lazy_lines | ranges::view::all;
auto begin = ranges::begin(rng);
auto end = ranges::end(rng);
auto acc = ranges::accumulate(begin, end, 0, acc_func);
std::cout << acc;

Ошибка как:

/opt/compiler-explorer/libs/rangesv3/trunk/include/range/v3/numeric/accumulate.hpp:39:15: note: candidate template ignored: requirement 'Accumulateable<ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::getlines_range::cursor>, int, (lambda at <source>:9:21), ranges::v3::ident>()' was not satisfied [with I = ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::getlines_range::cursor>, S = ranges::v3::default_sentinel, T = int, Op = (lambda at <source>:9:21), P = ranges::v3::ident, _concept_requires_38 = 42]

            T operator()(I begin, S end, T init, Op op = Op{}, P proj = P{}) const

              ^

godbolt.org / g / 3zjkLv


Принимая во внимание, что захват по ссылке все в порядке.

std::istringstream stack_iss;
auto acc_func = [&iss{stack_iss}](int acc, std::string &str) mutable {
    iss.str(str);
    int sz;
    iss >> sz;
    iss.clear();
    return acc + sz;

};
ranges::getlines_range lazy_lines = ranges::getlines(std::cin);
auto rng = lazy_lines | ranges::view::all;
auto begin = ranges::begin(rng);
auto end = ranges::end(rng);
auto acc = ranges::accumulate(begin, end, 0, acc_func);
std::cout << acc;

godbolt.org / g / SbpH61


Почему захват rvalue составляет std::istringstreamпо значению не соответствует концепции Accumulateable?

1 Ответ

0 голосов
/ 24 апреля 2018

Функторы, предоставляемые всем алгоритмам, должны быть копируемыми . Типы IOstream не копируются; они только для перемещения. И поэтому любая лямбда, содержащая их, не подлежит копированию.

Кроме того, вы также можете создавать istringstream внутри функтора; очистка и вставка новой строки не дешевле, чем их создание / уничтожение в каждом цикле.

...