With one exception, C++ only has unary operators and binary operators. The one exception is the ternary operator, exemplified by x = condition ? 0 : 42;. With regard to operator+, that is either a unary operator (e.g., +42) or a binary operator (40+2).
You can easily create a custom function that takes three ex1 objects as input and somehow computes the sum of those three objects. However, you cannot call this function operator+. There's no place in C++ for an operator+ that takes three arguments.
There are a number of ways around this restriction. The simplest is to create an overload of binary operator+ that computes the sum of a pair of ex1 objects, creating a new ex1 object as output. The statement ex1 d=a+b+c; will result in two calls to ex1 operator+(const ex1&, const ex1&). Both will create a temporary objects of type ex1. The temporary that represents the value of a+b+c is then passed to ex1::operator= to assign the value of that expression to d.
If you are doing this over and over and over, the creation of those temporary objects might well represent a performance bottleneck. If you are only doing this a few times, that performance bottleneck is a non-issue. The only time you need to worry is if this is an issue, and determining whether that's the case is an issue for you to resolve.
One way of overcoming this performance bottleneck is to create a function (or functions) that take more than two objects as input and creating a sum from those multiple objects. The downside is that you cannot name this function operator+, and hence you cannot use d=a+b+c. You'd instead have to use something like ex1::add_three(ex1&d, const ex1&a, const ex1&b, const ex1&c).
Another approach is to use expression templates as a means for implementing lazy evaluation. Your operator+(const ex1& a, constex1& b) doesn't actually calculate a+b. It instead creates an object that eventually will calculate a+b. The expression a+b+c in turn creates another object that eventually will calculate that result. Finally, the expression d=a+b+c evaluates that expression and assigns it to d, and (if implemented correctly) does so without creating any temporaries.
This approach has also its downsides. Sometimes it is better to create a temporary. The Eigen package does a very good job of determining when its better to create a temporary as opposed to using expression templates that defer calculation.
operator+functions which does nothing but print something and return a default-constructed object, of course with only two arguments to make it work. That way you can easily see that the function gets called two times for e.g.a + b + c, three times fora + b + c + detc.+operator) is a binary operator, meaning it has two operands: A left hand side and a right hand side. This is how addition works, in C++ as well as in real life. That the left hand side is the result of another addition doesn't really matter, the operator still has only two operands.