gpt4 book ai didi

c++ - 默认情况下不使用 std::next 的 Range-for 循环?

转载 作者:行者123 更新时间:2023-11-28 01:17:12 25 4
gpt4 key购买 nike

令我惊讶的是,默认情况下,基于范围的 for 循环缺少在 std::begin 返回的迭代器上调用 std::next 的自定义点,并且而是直接调用 operator++():

#include <iostream>

using namespace std;

struct Iterator {
Iterator& operator++()
{
cout << __PRETTY_FUNCTION__ << endl;
++i;
return *this;
}

int operator*()
{
return i;
}

int i;
};

bool operator!=(const Iterator& lhs, const Iterator& rhs)
{
return lhs.i != rhs.i;
}

Iterator& next(Iterator& it)
{
// this is where I need to injext my code :/
cout << __PRETTY_FUNCTION__ << endl;
return ++it;
}

struct Container {

Iterator begin() { return { 0 }; }
Iterator end() { return { 10 }; }
};

int main()
{
Container con;

for (const auto& elem : con) {
}
return 0;
}

知道为什么做出这个决定吗?知道如何在每次调用 operator++() 之前立即注入(inject)我的代码吗?

最佳答案

Any idea why this decision has been made?

没有。

And any idea how could I inject my code right before every call to operator++() then?

您可以编写一个容器包装器,它有一个 beginend 返回一些包装的迭代器,装饰 operator++。它需要大量样板,老实说,当您可以使用非基于范围的循环和零样板来实现相同的效果时,我不确定是否值得付出努力。不管怎样,你去吧:

#include <iostream>
#include <vector>
#include <iterator>
template <typename C,typename F>
struct container_wrapper {
template <typename iterator>
struct iterator_wrapper {
iterator base;
F func;
typename std::iterator_traits<iterator>::value_type operator*() {
return *base;
}
iterator_wrapper& operator++() {
func();
++base;
return *this;
}
bool operator !=(const iterator_wrapper& other) {
return base != other.base;
}
};
C& container;
F func;
iterator_wrapper<typename C::iterator> begin() { return iterator_wrapper<typename C::iterator>{ container.begin(),func }; }
iterator_wrapper<typename C::iterator> end() { return iterator_wrapper<typename C::iterator> { container.end(),func }; }
};

template <typename C,typename F>
container_wrapper<C,F> make_container_wrapper(C& c, F f) { return {c,f}; }

int main(){
std::vector<int> x{ 1,2,3,4,5,6};
for (const auto& x : make_container_wrapper(x,[](){std::cout << "\n";})) {
std::cout << x;
}

}

输出:

1
2
3
4
5
6

您可以传递一个 lambda 作为在递增之前执行的第二个参数。

PS:上面的代码应该适用于 C++11,而在较新的标准中它可能会稍微简单一些(例如,您不需要 make_.. 辅助函数来推导)。

关于c++ - 默认情况下不使用 std::next 的 Range-for 循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58308318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com