Last of all, what's stopping the compiler from interpreting 1 + 2 + 3 as 6? (Note I'm not sure if it will or not, just asking)
The compiler goes from left to right. The return type-value becomes a new left operand. So, if there has been a + overload returning a String before, these 1 + 2 + 3 will be treated as right operands - in turn - where the left one is a String.
You can't start with 2 ints (then they'll be summed as ints) unless you help a bit with parenthesis. Crude example:
Code:
#include <iostream>
#include <string>
#include <sstream>
std::string to_string(int n)
{
std::stringstream ss;
ss << n;
return ss.str();
}
struct MyString
{
std::string s;
MyString(const std::string& p = std::string()): s(p) {}
};
MyString operator+ (const MyString& a, const MyString& b)
{
return MyString(a.s + b.s);
}
MyString operator+ (const MyString& a, int i)
{
return MyString(a.s + to_string(i));
}
MyString operator+ (int i, const MyString& a)
{
return MyString(to_string(i) + a.s);
}
int main()
{
MyString a("TEXT"), b("END"), c, d;
c = 1 + 2 + a + 5 + 6 + b;
d = 1 + (2 + a) + 5 + 6 + b;
std::cout << c.s << '\n' //3TEXT56END
<< d.s << '\n'; //12TEXT56END
}
P.S Sebastian's code compiles and runs too, so there is a constructor that takes template parameters.