【发布时间】:2019-11-05 16:58:12
【问题描述】:
假设我有一个整数向量,并希望以一种奇怪的递归方式处理它(如果没有上下文,这种情况可能听起来很奇怪,但仍然如此)。
我想使用 const_iterators 来跟踪当前位置。这里是odd_recursive_stuff()原型:
// Note: changing "std::vector<int>::const_iterator& it_cur"
// into "std::vector<int>::const_iterator it_cur" will change
// the side effects!
void odd_recursive_stuff (std::vector<int>::const_iterator& it_cur,
std::vector<int>::const_iterator it_end);
首先我尝试这样称呼它:
void process_vec (const std::vector<int> &vec) {
odd_recursive_stuff (std::begin(vec), std::end(vec));
}
幸运的是,它没有编译(例如在 clang 8.0.0 中):
Error: no matching function for call to 'recursive_odd_stuff'
Candidate function not viable: expects an l-value for 1st argument!
因为std::begin()返回r-value,所以我不得不称它为另一种有效的方式:
void process_vec (const std::vector<int> &vec) {
std::vector<int>::const_iterator it_beg = std::begin (vec);
recursive_odd_stuff (it_beg, std::end(vec));
}
现在我想知道是否可以在没有local_variable it_beg 的单行中调用recursive_odd_stuff() 的基础?
似乎不可能编写另一个返回左值的begin() 版本,因为“函数的返回值是左值当且仅当它是引用时(C++03) . (5.2.2 [expr.call] / 10)”。那么唯一的方法就是用两行来调用它?
【问题讨论】:
-
您能否详细说明为什么需要引用
const_iterator? -
有问题吗?您始终可以将其包装在另一个函数中。也许像
recursive_odd_stuff和recursive_odd_stuff_impl之类的?不,begin 不能按值返回左值(不是引用),因为左值,粗略地说,必须命名。 -
不要引用可变的 const_iterator,而是考虑返回当前位置,而不是改变调用者的非临时参数。
-
Quimby 解决方案的好处是它把负担放在了执行方,而不是调用方。 (对于一个小项目,可能无关紧要。但在规模上,总是有助于注意强加给调用者而不是被调用者的负担。)
-
不,有时传递对迭代器的引用(或对任何类型对象的引用)是正确的做法。取决于要实现的目标以及功能的合同。我更喜欢尽可能地遵循价值语义,但这绝不是 C++ 行业中常见的“最佳实践”,它有它的粉丝和不喜欢它的人。
标签: c++ const-iterator