c++ - for loop bounds recalculated each iteration? -


suppose have class so:

class { public:     a(const size_t m, const size_t n) :         m_(m), n_(n), data_(m*n ? new double[m*n] : nullptr) {}     ~a() { delete[] data_; }      void foo() const {         // m_*n_ evaluated each iteration?         (size_t = 0; i<m_*n_; ++i)             data_[i] = 0.0;          // wont above?         (auto& : *this)             = 0.0;     }      double* begin() const { return data_; }     double* end() const { return data_ + m_*n_; }  private:     size_t m_, n_;     double* data_; }; 

since foo const , m_,n_ member variables, compiler should know these cannot change. product evaluated each time or compiler optimize away?

question 1:

   // m_*n_ evaluated each iteration?     (size_t = 0; i<m_*n_; ++i)         data_[i] = 0.0; 

answer: probably, never know. compilers getting pretty clever.

you improve odds lot declaring m_ , n_ const members. should anyway, imho, because logic of class requires it; if m_ or n_ change, data_ needs reallocated. declaring variables const tells compiler if can't see definitions of member functions of class, allowed assume m_ , n_ don't change.

question 2:

    (auto& : *this)         = 0.0; 

in case, end value not recomputed, definition. how range statement defined.

in general, there considerable difference between:

 (auto p = container.begin(), lim = container.end();       p != lim;       ++p) { ... } 

and

 (auto p = container.begin();       p != container.end();       ++p) { ... } 

in first case, assumption container not modified during loop, since modification invalidate iterators (such lim iterator). (there container types not true. container types, modification should avoided during loops.)

in second case, limit value computed every time, if container modified there no problem. @ least, there no problem end test. still need ensure p cannot invalidated, , container types -- unordered maps , sets, example -- sequence of elements can altered modification, adding new element might cause elements missing iteration.

the range syntax for ( variable : expression) explicitly defined translated first of above iteration styles, limit computed once @ beginning of iteration, , consequently mutations might invalidate limit iterator result in undefined behaviour.

in cases, should avoid such mutations , should use range syntax or equivalent style. there applications in recomputing limit each time appropriate. best example of such use-case worklist, can modeled std::deque:

for (auto work = workqueue.begin();      work != workqueue.end();      ++work) {   /* ... */   if (some_condition) {     work_queue.emplace_back(work_item);   }   /* ... */ } 

that's common style in graph algorithms, example.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -