2

In C++, we can define and overload operators to make the code beautiful. However, when an operator needs to be called from within the class which defines it, the syntax isn't as elegant.

For example, consider the typical use of operator[] on a string:

std::string word("Hello!");
char first = word[0];

Simple. But what if such an operator needs to invoked from within some class which itself defines it? The syntaxes aren't as pretty:

(*this)[i];//option 1
operator[](i);//option 2
this->operator[](i);//option 3

In terms of performance and/or behavior, what is the difference between the three, especially when dealing with inheritance or polymorphism? Which is the proper, unambiguous syntax?

ayane_m
  • 962
  • 2
  • 10
  • 26
  • What do you want to achieve actually? – πάντα ῥεῖ Dec 02 '16 at 06:52
  • Your changed title doesn't answer my question. – πάντα ῥεῖ Dec 02 '16 at 06:57
  • "in terms of readability" -- That's subjective and probably not a good question for SO. "and performance" -- That can be measured objectively, but measuring produces only results for that specific compiler and that specific combination of compiler options. –  Dec 02 '16 at 06:58
  • @πάνταῥεῖ How about now? – ayane_m Dec 02 '16 at 06:58
  • Performance of what? How is `operator[]` implemented? Where and how is it supposed to be called. – πάντα ῥεῖ Dec 02 '16 at 06:59
  • @πάνταῥεῖ Is there a difference in the assembler that the compiler generates? If so, what is the difference, and does this difference entail different behaviors? – ayane_m Dec 02 '16 at 07:01
  • @彩音M Did you consider to compare the emitted assembler codes? E.g. with GCC you could use the `-E` flag to inspect the assemler. – πάντα ῥεῖ Dec 02 '16 at 07:02
  • @πάνταῥεῖ `-S`, not `-E`. `-E` shows preprocessor output. –  Dec 02 '16 at 07:04
  • @hvd Ooops, yes. `-S` of course. – πάντα ῥεῖ Dec 02 '16 at 07:07
  • 1
    The choice between option 2 and option 3 always exists when you access a member function from within another member function. I.e. it is not in any way specific to overloaded operators. For this reason the distinction between 2 and 3 is probably completely irrelevant in the context of this question, which focuses on operators specifically. – AnT stands with Russia Dec 02 '16 at 07:14
  • @AnT I think you're on to something. Can you elaborate? It may not be irrelevant, but in either case, I'm still curious. – ayane_m Dec 02 '16 at 07:21
  • @彩音M: I'm just saying that [almost] every time you want to call member function `bar()` from another member function of the same class, you can just call it as `bar()` or, if you wish, as `this->bar()`. That's exactly your options 2 and 3. I.e. the choice between 2 and 3 has nothing to do with overloaded operators. – AnT stands with Russia Dec 02 '16 at 07:51
  • @AnT But why "almost"? In what scenario would they not be alike? (I meant "relevant" in my prior comment, not *ir*relevant.) – ayane_m Dec 02 '16 at 07:53
  • 1
    @彩音M: That "almost" is about a different issue. If your class is a template class and `bar()` belongs to its base class, which is also a template, then a mere `bar()` will not "see" the function. In this case explicit `this->bar()` is one way to force the compiler to perform name lookup in the base class. See http://stackoverflow.com/questions/4643074/why-do-i-have-to-access-template-base-class-members-through-the-this-pointer. – AnT stands with Russia Dec 02 '16 at 07:56

1 Answers1

6

What is the difference between the three, in terms of readability and performance?

There should be no difference in performance no matter which form you use.

As for readability, it's a matter of opinion. I would prefer to use

(*this)[i];

but I wouldn't complain if someone used one of the other forms.

Which is the "correct" way of invoking the operator?

All are correct - syntactically as well as semantically.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 2
    If I need to use it in multiple places in a single function, then first of all I do this : `auto & self = *this;` (cv-qualified as per semantic) and then use `self[i]` everytime I need it. – Nawaz Dec 02 '16 at 07:27
  • For comical effect: i[*this]? ;) – Mats Petersson Dec 02 '16 at 08:28
  • @MatsPetersson: `i[*this]` would **not** work. That is where `operator[]` for user-defined types and built-in types differ. The pointers/arrays support *pointer-arithmetic* because of which `i[pointer]` and `pointer[i]` *both* works and are equivalent. – Nawaz Dec 02 '16 at 09:06