Question

Here is an exercise from C++ Primer 5th Edition:

Exercise 14.26: Define subscript operators for your StrVec, String, StrBlob, and StrBlobPtr classes.(P.566)

The class StrVec compiled without any error nor warning.Below is the class body:

/**
 * @brief   The StrVec class  a std::vector like class without template
 *          std:string is the only type it holds.
 */
class StrVec
{
public:
    //! default constructor
    StrVec():
        element(nullptr), first_free(nullptr), cap(nullptr){}

    // etc      

    //! public members
          std::string& operator [](std::size_t n)       {return element[n];}
    const std::string& operator [](std::size_t n) const {return element[n];}  
    //                                            ^^^^^
    // etc    
private:    
    //! data members
    std::string* element;       //  pointer to the first element
    std::string* first_free;    //  pointer to the first free element
    std::string* cap;           //  pointer to one past the end

    std::allocator<std::string> alloc;
    // etc
};

When compiling the class String, a warning was generated, as shown below:

/**
 * @brief std::string like class without template
 *
 *        design:
 *
 *        [0][1][2][3][unconstructed chars][unallocated memory]
 *        ^           ^                    ^
 *        elements    first_free           cap
 */
class String
{
public:
    //! default constructor
    String();

    // etc

          char operator [](std::size_t n)       {return elements[n];}
    const char operator [](std::size_t n) const {return elements[n];}
    //                                    ^^^^^
private:    
    //! data members
    char* elements;
    char* first_free;
    char* cap;

    std::allocator<char> alloc;    
    // etc
};

Warning from the compiler:

warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
     const char operator [](std::size_t n) const {return elements[n];}
                                           ^

The compiler I was using:

gcc version 4.8.1 (Ubuntu 4.8.1-2ubuntu1~13.04) 

Why is it so? Is there any significant difference between the two classes?

Was it helpful?

Solution

const char operator [](std::size_t n) const {return elements[n];} This returns a const copy of elements[n], which is no use at all. You return a const when you don't want the caller changing your stuff, but since you're returning a copy here, you wouldn't be changing anything anyways.

Your first example is returning a const reference, which is what you should do here.

OTHER TIPS

The first version is returning a reference to an array element. Whether or not this is a const reference determines whether you can just read the element's value or write to the element also.

The second version is returning a copy of an array element. If this is deliberate, you only need

char operator [](std::size_t n) const {return elements[n];}

If you wanted two overloads of operator [], one that allows an element to be read and another that allows it to be written, you need to return references instead

      char& operator [](std::size_t n)       {return elements[n];}
const char& operator [](std::size_t n) const {return elements[n];}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top