Some ideas about dot operator overloding.
Sample 1:
class C { public: int get() { return 1; } }; int operator . square(const C& r) { return r.get() * r.get(); } int main() { C c; c.square(); //ok square(c); //ok }
Sample 2:
What happens if C::square exists?
class C { public: int get() { return 1; } int square() const { return r.get() * r.get(); } }; //Error, ambiguous C already have C::square int operator . square(const C& r) { return r.get() * r.get(); }
Sample 3:
Enabling uniform call.
class C { public: int get() { return 1; } int square() const { return r.get() * r.get(); } }; using int operator . square(const C& r); int main() { C c; c.square(); //ok square(c); //ok }
Sample 3:
Uniform call not enabled.
class C { public: int get() { return 1; } int square() const { return r.get() * r.get(); } }; int main() { C c; c.square(); //ok square(c); //error }
Sample 4:
For non-class types.
std::string operator . tostring(int i) { ... } int main() { int i = 1; std::string s = i.tostring(); }
Sample 5:
Syntax alternatives
class C { public: int get() { return 1; } }; int operator C::square() const { return this.get() * this.get(); }
References
How Non-Member Functions Improve Encapsulation - Scott Meyers