gunnar.s gunnar.s - 1 month ago 19
C++ Question

Effective C++, Third edition: Overloading const function

i'm trying to learn some best practices for C++ coding with the book "Effective C++, Third edition".

In item 3, the authors talk about

const
in member functions.
They give an example class for which they overload the
[]
operator twice - once for non-const and once for const objects.
The following code is given:

class TextBlock {
public:
...
const char& // operator[] for
operator[](const std::size_t position) const // const objects
{ return text[position]; }
char& // operator[] for
operator[](const std::size_t position) const // non-const objects
{ return text[position]; }
private:
std::string text;
};





TextBlock tb("Hello");
std::cout << tb[0]; // calls non-const
// TextBlock::operator[]
const TextBlock ctb("World");
std::cout << ctb[0]; // calls const TextBlock::operator[]


So i tried to implement this snippet just to get some practice.

#include <iostream>
#include <string>

class text_block
{
public:
text_block(const std::string& s);
const char& operator[](const std::size_t position) const;
char& operator[](const std::size_t position) const;
private:
std::string s;
};

text_block::text_block(const std::string& s) : s(s) {}

const char& text_block::operator[](const std::size_t position) const
{
return s[position];
}

char& text_block::operator[](const std::size_t position) const
{
return s[position];
}

int main()
{
text_block tb("non-const");
const text_block ctb("const");

std::cout << tb[0] << std::endl << ctb[0] << std::endl;

return 0;
}


However,
g++ 6.1.1
gives me several errors, e.g.,
error: ‘char& text_block::operator[](std::size_t) const’ cannot be overloaded
.

As I understood the explanations from the book, both implementations of the
[]
operator should distinguish the behavior between
const
and non-
const
objects of
text_block
. Therefore, shouldn't the
const
modifier be omitted at the end of the signature for the non-
const
version? Is this a mistake in the book or am I missing something?

Kind regards,
Gunnar

Answer

You specified both overloads as const

    const char& operator[](const std::size_t position) const;
    char& operator[](const std::size_t position) const;

Just remove the const specifier from the one that shouldn't be const.

    const char& operator[](const std::size_t position) const;
    char& operator[](const std::size_t position);

You get an error, because both overloads have matching parameters (for the purpose of overload resolution). Therefore it's considered a redefinition.