4 ms·
I don't like auto over int, and other primitives. But auto in for loops or with iterators seems the way to go and is a bless!
by Ciberth 7y ago
I don't like auto over int, and other primitives. But auto in for loops or with iterators seems the way to go and is a bless!
- imedadel 7y agoThat's what I've been doing. My issue is whether using auto would affect performance.
- xorz57 7y agoJust keep in mind that auto is different than const auto. Performance won't be an issue.
- mehrdadn 7y agoWith begin()/end() it's probably fine, but for-each loops it's not a great idea since then you run into problems when there was a cast intended. The main (only?) example of this pattern in the standard is vector<bool>, so of course people's immediate reaction to blame this on vector<bool>. However that's just the example currently in the standard, and people use it for other things too. By using auto you end up writing code that can break. Example: typedef std::vector<bool> Vec; Vec f(1, false); for (typename Vec::value_type &&x : f) { std::cout << typeid(x).name() << std::endl; } for (auto &&x : f) { std::cout << typeid(x).name() << std::endl; }
- nemetroid 7y agoDo you have examples of cases other than vector<bool> where this is an issue?
- mehrdadn 7y agohttps://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html https://eigen.tuxfamily.org/dox/TopicLazyEvaluation.html https://stackoverflow.com/q/46321667 https://stackoverflow.com/q/46321667
- nemetroid 7y agoThanks, those were interesting to read about. It doesn't seem like something that would come up in the for loop case, though.
- mehrdadn 7y agoI mean, you can imagine proxies for stuff beside bools and matrices... template<class It> struct iterator_range { It b, e; It begin() const { return b; } It end() const { return e; } }; template<class It> iterator_range<It> make_iterator_range(It b, It e) { iterator_range<It> r = { b, e }; return r; } template<class T> struct endian_reversed_iterator { T *p; struct reference { T *p; operator T() const { return boost::endian::endian_reverse(*p); } reference &operator =(T const &other) const { *p = boost::endian::endian_reverse(other); } }; endian_reversed_iterator(T *p) : p(p) { } reference operator *() { reference r = { p }; return r; } endian_reversed_iterator &operator++() { ++p; return *this; } bool operator!=(endian_reversed_iterator const &other) const { return p != other.p; } }; int main() { unsigned arr[] = { 1, 2 }; for (auto x : make_iterator_range<endian_reversed_iterator<unsigned> >(&arr[0], &arr[2])) { ++x; // whatever } }