我的代码中有以下for
语句:
for (auto Iter = Target.begin(),
IterEnd = std::stable_partition(Target.begin(), Target.end(), Check);
Iter != IterEnd; ++Iter)
{ /* loop statement */ }
重点是循环不会修改容器的元素,因此将迭代器声明为const_iterator
是有意义的。对于第一个使用cbegin()
来说,我可以轻松解决问题,但是第二个更为复杂。我不能在cbegin()
中声明cend()
和stable_partition
,因为当然stable_partition
需要non const_iterators
才能完成工作。
可能的解决方案是将auto替换为正确的类型,本例中为std::vector< std::string >::const_iterator
。这会在第二次分配时强制从iterator
转换为const_iterator
。
但是,我不喜欢它。类型很容易迅速变得难以管理,因此我正在寻找一种解决方案,使我可以使用auto,而无需在循环外声明一些怪异的东西。有什么建议吗?
答案 0 :(得分:2)
我认为最清晰的解决方案是将std::stable_partition
放在for
之前。这将产生等效的算法。
问题是stable_partition
返回了可以修改元素的迭代器。幸运的是,从container::iterator
到container::const_iterator
有一个隐式转换(对于大多数标准容器)。要进行转换,您可以使用IterEnd
或std::vector<T::const_iterator
或我的个人喜好指定decltyp(Target.cbegin()
的类型:
auto Iter = Target.cbegin();
decltype(Iter) IterEnd = std::stable_partition(Target.begin(), Target.end(), Check);
for (; Iter != IterEnd; ++Iter)
{
}
为完整起见,您可以根据需要将所有内容保留在for
内,但我认为它不太可读:
for (auto Iter = Target.cbegin(),
IterEnd = (decltype(Iter)) std::stable_partition(Target.begin(), Target.end(), Check);
Iter != IterEnd;
++Iter)
{}
答案 1 :(得分:0)
这是通过功能界面表达想法的一种方法:
#include <vector>
#include <algorithm>
#include <iostream>
namespace detail {
template<class Container, class F>
struct const_partitioned_target
{
using container_type = std::decay_t<Container>;
using const_iterator = typename container_type::const_iterator;
const_partitioned_target(Container& cont, F f)
: first(cont.cbegin())
, last(std::partition(cont.begin(), cont.end(), f))
{
}
const_iterator begin() const { return first; }
const_iterator end() const { return last; }
const_iterator first, last;
};
}
template<class Container, class F>
auto const_partitioned_target(Container& cont, F&& f)
{
return detail::const_partitioned_target<Container, std::decay_t<F>>(cont, std::forward<F>(f));
};
int main()
{
std::vector<int> Target { 1, 2, 6, 9, 10, 20, 30, 40 };
auto Check = [](auto&& x)
{
return x < 10;
};
for(auto&& elem : const_partitioned_target(Target, Check))
{
// elem will have the type: int const&
std::cout << elem << '\n';
}
}
预期输出:
1
2
6
9