82

It would be very useful to be able to overload the . operator in C++ and return a reference to an object.

You can overload operator-> and operator* but not operator.

Is there a technical reason for this?

skaffman
  • 398,947
  • 96
  • 818
  • 769
Ferruccio
  • 98,941
  • 38
  • 226
  • 299
  • 4
    Can you give an example of when you want to override the '.' operator? – Toon Krijthe Feb 06 '09 at 12:01
  • 6
    Generally, the use case is "smart references". A kind of Proxy. – ddaa Feb 06 '09 at 12:12
  • 2
    @Gamecat: Read through [this](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1671.pdf) proposal to add the ability to overload `operator.` and `operator.*`, it has a few examples. – Mankarse Feb 12 '12 at 02:46
  • But you can't overload `->` or `*` on pointers! – curiousguy Aug 26 '15 at 09:39
  • how do you overload on pointers ? the overloading is with respect to the class, not the instances(objects) so at the time of overloading, we don't know if you are going to make pointers or not – Xsmael Oct 13 '15 at 17:30
  • 1
    @ToonKrijthe Spaces around `.` are allowed, so perhaps some clever but appalling dynamic dispatch hack that allows for expressing dot product as `matrix1 . matrix2`. – mwcz Oct 25 '15 at 00:31
  • 5
    ["Operator Dot", proposal by Stroustrup and Dos Reis](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4173.pdf) – Emil Laine May 08 '16 at 00:43
  • Here's a later version of the Stroustrup/Dos Reis Operator Dot proposal: http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0416r1.pdf – Some Guy May 29 '22 at 04:14
  • Here's a competing proposal for solving many of the same problems, which tries to use a special form of inheritance instead of overloading the dot operator: https://open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0352r1.pdf – Some Guy May 29 '22 at 04:15

4 Answers4

63

See this quote from Bjarne Stroustrup:

Operator . (dot) could in principle be overloaded using the same technique as used for ->. However, doing so can lead to questions about whether an operation is meant for the object overloading . or an object referred to by . For example:

class Y {
public:
    void f();
    // ...
};

class X {    // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};

void g(X& x)
{
    x.f();    // X::f or Y::f or error?
}

This problem can be solved in several ways. At the time of standardization, it was not obvious which way would be best. For more details, see The Design and Evolution of C++.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • Full quote from TDaEoC++ in my answer. – ddaa Feb 06 '09 at 12:11
  • 16
    I am tempted to vote this down for plagiarism/recoloring. When quoting, quote verbatim, don't tweak. And use the quote formats. – Sebastian Mach Feb 17 '12 at 14:02
  • 2
    The example is just overload resolution ambiguity, pointing to a need for more careful programming ( see: http://stackoverflow.com/questions/13554606/ambiguity-not-picked-up-by-compiler ) This situation should not serve as a reason to not overload `operator .` – slashmais May 29 '13 at 16:15
  • @slashmais No. The justification of `operator.` is an explicit parallel with `operator->`. And how could you do overloading resolution? – curiousguy Aug 26 '15 at 10:19
  • Just to note that later on, Bjarne Stroustrup was in favor of _operator dot_ and even pushed a proposal for that, which apparently was not (yet) accepted: [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf) - as already added by @emlai as a comment to the question – Amir Kirsh Dec 03 '20 at 19:52
  • Here's a later version of the proposal: http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0416r1.pdf – Some Guy May 29 '22 at 04:01
  • Here's a competing proposal for solving many of the same problems, which tries to use a special form of inheritance instead of overloading the dot operator: https://open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0352r1.pdf – Some Guy May 29 '22 at 04:02
52

Stroustrup said C++ should be an extensible, but not mutable language.

The dot (attribute access) operator was seen as too close to the core of the language to allow overloading.

See The Design and Evolution of C++, page 242, section 11.5.2 Smart References.

When I decided to allow overloading of operator ->, I naturally considered whether operator . could be similarly overloaded.

At the time, I considered the following arguments conclusive: If obj is a class object then obj.m has a meaning for every member m of that object's class. We try not to make the language mutable by redefining built-in operations (though that rule is violated for = out of dire need, and for unary &).

If we allowed overloading of . for a class X, we would be unable to access members of X by normal means; we would have to use a pointer and ->, but -> and & might also have been re-defined. I wanted an extensible language, not a mutable one.

These arguments are weighty, but not conclusive. In particular, in 1990 Jim Adcock proposed to allow overloading of operator . exactly the way operator -> is.

The "I" in this quote is Bjarne Stroustrup. You cannot be more authoritative than that.

If you want to really understand C++ (as in "why is it this way"), you should absolutely read this book.

leemes
  • 44,967
  • 21
  • 135
  • 183
ddaa
  • 52,890
  • 7
  • 50
  • 59
  • 1
    As is pointed out in other comments, Stroustrup has apparently changed his mind on this issue and has himself presented (in 2016) a proposal for allowing overloaded operator ".". See https://isocpp.org/blog/2016/02/a-bit-of-background-for-the-operator-dot-proposal-bjarne-stroustrup for some of his comments on why he did so. – Some Guy May 29 '22 at 04:05
28

Stroustrup has an answer for this question:

Operator . (dot) could in principle be overloaded using the same technique as used for ->. However, doing so can lead to questions about whether an operation is meant for the object overloading . or an object referred to by . For example:

class Y {
public:
    void f();
    // ...
};
class X {   // assume that you can overload .
    Y* p;
    Y& operator.() { return *p; }
    void f();
    // ...
};
void g(X& x)
{
    x.f();  // X::f or Y::f or error?
}

This problem can be solved in several ways. At the time of standardization, it was not obvious which way would be best. For more details, see D&E.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
mfazekas
  • 5,589
  • 1
  • 34
  • 25
1

It is very easy to understand, if you go through the internal mechanism of operator function invocation, Say a class complex can have two member r for real part and i for imaginary part. Say Complex C1(10,20),C2(10,2) // we assume there is an already a two argument constructor within class. Now if you write C1+C2 as a statement then compiler try to find the overloaded version of + operator on complex number. Now we assume that I overload + operator, so C1+C2 internally translated as c1.operator+(c2) Now assume for the time beings you can overload '.' operator. so now think following call C1.disp()//display content of a complex object Now try to represent as an internal representation C1.operator.(------) , completely messy things created. That is the reason why we can't overload '.' operator

  • 1
    Some people say internal translated should not call overloaded `operator.` – curiousguy Aug 29 '15 at 14:03
  • See a C++ proposal for how this can be useful and not so messy: [http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf) – Amir Kirsh Dec 03 '20 at 19:55
  • Here's a later version of the proposal: http://open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0416r1.pdf – Some Guy May 29 '22 at 04:08
  • Here's a competing proposal for solving many of the same problems, which tries to use a special form of inheritance instead of overloading the dot operator: https://open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0352r1.pdf – Some Guy May 29 '22 at 04:09