e***@live.com
2018-10-09 12:05:44 UTC
I think it is painful and noisy to write iterators in order to support
range-for loop.
Here are my reasons:
1: semantics of range-for loop are not necessarily equivalent to access
every iterator in the range.
2: For many containers, defining iterators are harder than defining the
range-for loop directly.
3: It is painful to write iterators to support simple data structures.
4: For containers like std::deque, std::set, std::map and even lists, using
iterators to traverse the entire container lose a huge amount of
performance compared to define a universal for_each function.
For example, if I have a binary search tree:
template<typename T>
class bst
{
};
template<typename T,typename Callback>
void inorder_traverse(const bstnode<T> *p,Callback &&F)
{
if(p->left())
inorder_travel(p->left(),F);
F(p->value());
if(p->right())
inorder_travel(p->right(),F);
}
template<typename T,typename Callback>
inline void for_each(const bst<T> &t,Callback &&F)
{
if(t.root())
inorder_traverse(t.root(),std::forward<Callback>(F));
}
bst<std::size_t> b;
std::size_t sum(0);
for(const auto &ele : b) // will check whether the "for_each" function
is defined for the container. If it does have one, call this first.
sum+=ele;
this will be equivalent to:
bst<std::size_t> b;
std::size_t sum(0);
for_each(b,[&](const auto &ele)
{
sum+=ele;
});
range-for loop.
Here are my reasons:
1: semantics of range-for loop are not necessarily equivalent to access
every iterator in the range.
2: For many containers, defining iterators are harder than defining the
range-for loop directly.
3: It is painful to write iterators to support simple data structures.
4: For containers like std::deque, std::set, std::map and even lists, using
iterators to traverse the entire container lose a huge amount of
performance compared to define a universal for_each function.
For example, if I have a binary search tree:
template<typename T>
class bst
{
};
template<typename T,typename Callback>
void inorder_traverse(const bstnode<T> *p,Callback &&F)
{
if(p->left())
inorder_travel(p->left(),F);
F(p->value());
if(p->right())
inorder_travel(p->right(),F);
}
template<typename T,typename Callback>
inline void for_each(const bst<T> &t,Callback &&F)
{
if(t.root())
inorder_traverse(t.root(),std::forward<Callback>(F));
}
bst<std::size_t> b;
std::size_t sum(0);
for(const auto &ele : b) // will check whether the "for_each" function
is defined for the container. If it does have one, call this first.
sum+=ele;
this will be equivalent to:
bst<std::size_t> b;
std::size_t sum(0);
for_each(b,[&](const auto &ele)
{
sum+=ele;
});
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9ba3d13b-3044-4223-afd0-218e8ba06893%40isocpp.org.
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9ba3d13b-3044-4223-afd0-218e8ba06893%40isocpp.org.