为啥按值捕获 std::istringstream 的右值的 Op 无法满足 Accumulateable 概念?
Posted
技术标签:
【中文标题】为啥按值捕获 std::istringstream 的右值的 Op 无法满足 Accumulateable 概念?【英文标题】:Why does Op that captures rvalue of std::istringstream by value fails the Accumulateable concept?为什么按值捕获 std::istringstream 的右值的 Op 无法满足 Accumulateable 概念? 【发布时间】:2018-04-24 14:38:14 【问题描述】:这不会编译:
auto acc_func = [issstd::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 = [&issstack_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
为什么按值捕获std::istringstream
的右值会使Accumulateable
概念失败?
【问题讨论】:
【参考方案1】:提供给所有算法的函子必须是可复制的。 iostream 类型不可复制;他们只能移动。因此,任何包含它们的 lambda 都是不可复制的。
此外,您还可以在函子内创建istringstream
;清除它并插入一个新字符串并不比在每个周期中构造/销毁它们便宜。
【讨论】:
这是因为它们可以在实现中使用值语义传递吗?以上是关于为啥按值捕获 std::istringstream 的右值的 Op 无法满足 Accumulateable 概念?的主要内容,如果未能解决你的问题,请参考以下文章
C++ 使用 istringstream 将整数读取为无符号字符
C ++ 11 lambda捕获`this`并按值捕获局部变量