On 3/12/2019 15:46, Emil Dotchevski wrote:
I wonder if it is possible to implement op+ such that if one writes:
x = a+b;
the return value of a+b gets converted to the type of x. The motivation is that, as a user, I've determined a fixed size limit for x, and therefore the library should use that, and if it is exceeded at run-time, it makes sense for the behavior to be the same as when any other fixed_string capacity is exceeded (e.g. boost::throw_exception).
It is possible, by using a deferred execution pattern. operator+ would return a unique type which contains the references to a and b (not yet concatenated) and implements a templated implicit cast operator for fixed_string<N>, which is where the concatenation is actually performed (since it then knows the target type). This also works when passing parameters -- at least when those parameters are declared with an explicit fixed_string<N> type. The caveat is that it doesn't work with "auto" variables, or with templated parameters. This limitation unfortunately is quite a large one, and can be quite aggravating in practice. (Another caveat is that those cases that "don't work" above can easily cause dangling references and other lifetime issues instead of cleanly failing to compile.) Given that, I don't think I'd recommend actually doing it. The reference-lifetime-safe alternative is to return an object that contains a copy of the parameters, but this is now strictly worse than just returning a fixed_string. (And, when you then try to assign this to a fixed_string<N>, reintroduces the problem of what to do when a.size()+b.size() > N, since it will probably often be the case that A+B
N, and this is not a mistake.)