Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6854075
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 27, 20262026-05-27T01:35:20+00:00 2026-05-27T01:35:20+00:00

I found this interesting line in: a book http://www.acceleratedcpp.com/ – sources – chapter 11

  • 0

I found this interesting line in: a book http://www.acceleratedcpp.com/ – sources – chapter 11 – Vec.h (I is a std::vector remake)

And I don’t really understand what is this version of operator good for. Why should there be two versions (const and a non-const) of this operator defined?

I even tried it out and it seems to me, that the non-const version is called all the time…
Can you please explain?

#include <iostream>
#include <algorithm>
#include <cstddef>
#include <memory>
using namespace std;

template <class T> class Vec {
public:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef size_t size_type;
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;

    Vec() { create(); }
    explicit Vec(size_type n, const T& t = T()) { create(n, t); }

    Vec(const Vec& v) { create(v.begin(), v.end()); }
    Vec& operator=(const Vec&); // as defined in 11.3.2/196
    ~Vec() { uncreate(); }

    T& operator[](size_type i) { cout << "T&";return data[i]; }
    const T& operator[](size_type i) const { cout << "const T&!";return data[i]; }

    void push_back(const T& t) {
        if (avail == limit)
            grow();
        unchecked_append(t);
    }

    size_type size() const { return avail - data; }  // changed

    iterator begin() { return data; }
    const_iterator begin() const { return data; }

    iterator end() { return avail; }                 // changed
    const_iterator end() const { return avail; }     // changed
    void clear() { uncreate(); }
    bool empty() const { return data == avail; }

private:
    iterator data;  // first element in the `Vec'
    iterator avail; // (one past) the last element in the `Vec'
    iterator limit; // (one past) the allocated memory

    // facilities for memory allocation
    std::allocator<T> alloc;    // object to handle memory allocation

    // allocate and initialize the underlying array
    void create();
    void create(size_type, const T&);
    void create(const_iterator, const_iterator);

    // destroy the elements in the array and free the memory
    void uncreate();

    // support functions for `push_back'
    void grow();
    void unchecked_append(const T&);
};

template <class T> void Vec<T>::create()
{
    data = avail = limit = 0;
}

template <class T> void Vec<T>::create(size_type n, const T& val)
{
#ifdef _MSC_VER
    data = alloc.allocate(n, 0);
#else
    data = alloc.allocate(n);
#endif
    limit = avail = data + n;
    std::uninitialized_fill(data, limit, val);
}

template <class T>
void Vec<T>::create(const_iterator i, const_iterator j)
{
#ifdef _MSC_VER
    data = alloc.allocate(j - i, 0);
#else
    data = alloc.allocate(j - i);
#endif
    limit = avail = std::uninitialized_copy(i, j, data);
}

template <class T> void Vec<T>::uncreate()
{
    if (data) {
        // destroy (in reverse order) the elements that were constructed
        iterator it = avail;
        while (it != data)
            alloc.destroy(--it);

        // return all the space that was allocated
        alloc.deallocate(data, limit - data);
    }
    // reset pointers to indicate that the `Vec' is empty again
    data = limit = avail = 0;

}

template <class T> void Vec<T>::grow()
{
    // when growing, allocate twice as much space as currently in use
    size_type new_size = max(2 * (limit - data), ptrdiff_t(1));

    // allocate new space and copy existing elements to the new space
#ifdef _MSC_VER
    iterator new_data = alloc.allocate(new_size, 0);
#else
    iterator new_data = alloc.allocate(new_size);
#endif
    iterator new_avail = std::uninitialized_copy(data, avail, new_data);

    // return the old space
    uncreate();

    // reset pointers to point to the newly allocated space
    data = new_data;
    avail = new_avail;
    limit = data + new_size;
}

// assumes `avail' points at allocated, but uninitialized space
template <class T> void Vec<T>::unchecked_append(const T& val)
{
    alloc.construct(avail++, val);
}

template <class T>
Vec<T>& Vec<T>::operator=(const Vec& rhs)
{
    // check for self-assignment
    if (&rhs != this) {

        // free the array in the left-hand side
        uncreate();

        // copy elements from the right-hand to the left-hand side
        create(rhs.begin(), rhs.end());
    }
    return *this;
}

int main() {
    Vec<int> v;
    v.push_back(5);


    cout << v[0] << endl; // even now the non-const version is called!

    system("pause");
}

Thanks!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-27T01:35:21+00:00Added an answer on May 27, 2026 at 1:35 am

    Quite surely that was

     const T& operator[](size_type i) const // <-- note the extra const
    

    Const signals the compiler that the return value may not be modified by the calling code.

    This has to do with:

    • returning by reference would be unsafe if the reference would be modifiable
    • returning by reference can be a lot more efficient than returning by value
    • non-const methods cannot be called on const objects (instances)

    Rationale: if the declaring object itself is const there would be no way for the method to return a reference to a (part of) a member non-const; Const-ness cascades if you will: this is known as const-correctness.

    In practice you will often see const/non-const overloads like so:

    class Container
    {
        private: 
           int data[10];
        public:
           int       & operator[](int i)       { return data[i]; }
           int const & operator[](int i) const { return data[i]; }
    };
    
    //
    Container x;
    Container& r = x;
    const Container& cr = x;
    
    x [3] += 1;
    r [3] += 1;  // just fine, non-const overload selected
    cr[3] += 1;  // compile error, return value `const &`
    

    Related topics:

    • Largely the same goes for the lesser-known volatile modifier
    • A related keyword (the inverse, if you will) to const is mutable
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

In Matters Computational I found this interesting linear search implementation (it's actually my Java
Reading about the G.729 codec , I found this interesting tidbit about Comfort Noise
I read This article and i found it interesting. To sum it up for
I found this link http://artis.imag.fr/~Xavier.Decoret/resources/glsl-mode/ , but there isn't a lot of description around
I found this interesting post explaining how to use saxparser for large xml files
I found this interesting blog post via CodingHorror: My Favorite Interview Question . In
I've always found this interesting, and haven't managed to fully understand it yet. Take
I found this interesting thing when I was trying out the new feature optional
I found (after another question here on StackOverflow) this interesting library written in Python
Making a migration from 2.8.1 to 2.9.1 found interesting thing. Tried to write this

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.