Pitfalls of C++’s subscript operator

September 23, 2004 at 12:59 am (PT) in Programming

What’s wrong with this C++ code?

#include <iostream>
#include <string>

class Foo { public: Foo() { }
operator bool() { return true; }
std::string operator[](const std::string& s) { return s; } };
int main(void) { Foo foo; std::cout << foo["hello world!"] << std::endl; return 0; }

Answer:

Trying to compile the above code with gcc produces the following error:

In function `int main()':
ambiguous overload for `Foo &[const char[13]]'
candidates are: operator [](int, const char *) <builtin>
                class string Foo::operator [](const string &)

Wha—? Where the heck did operator[](int, const char*) come from?

This little bit of goofiness is inherited from C. In C, the subscript operator is unintuitively commutative. That is, ptr[index] is exactly the same as index[ptr]!

In C, this is never a problem. Nobody writes code like index[ptr], and you can be blissfully ignorant that it’s allowed at all.

In C++, it can manifest itself where you don’t expect it, and this is what happens in the code above.

The compiler tries to parse the expression foo["hello world!"]. Foo doesn’t have an operator[](const char*) method (nor an operator[](const char[13]) one), so the compiler has two choices:

  • It can coerce "hello world!" to a std::string and call Foo::operator[](const std::string&).
  • Since Foo has operator bool() defined, the compiler can cast foo to a bool. Now the expression involves a bool (an integer type) and a string literal (a character array), and because the subscript operator is commutative for this situation, it is legal to use the bool as an index into "hello world!".

Each choice involves one cast, so the compiler considers both equally valid and can’t decide.

To fix this, we can add Foo::operator[](const char*) and make the const char* to std::string coercion explicit:

class Foo
{
public:
    // ...

std::string operator[](const char* s) { return operator[](std::string(s)); } }

Tags:

Newer: Pretension
Older: Microsoft Outlook hates me.

1 Comment »

  1. hard core. i miss programming. i get further and further away from this crap each year.

    — ben @ October 22, 2006, 6:13 pm (PT)

RSS feed for comments on this post.

Leave a comment

(will never be displayed)


Allowed HTML tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>