Entonces, "const Foo& f" es lo mismo que "Foo const& f"?
Es lo mismo sí.
Hay alguna manera de hacer "constante referencia a Foo" y no "referencia a Foo constante"?
Foo& variable -> "constante referencia a Foo"
const Foo& variable -> "referencia a Foo constante"
Cuando declaras una referencia, el compilador te obliga a darle un valor en ese mismo momento. Despuées de la inicialización, verás que no vas a poder modificar la referencia. Es decir, el enlace de referencia es constante siempre. Debido a esto, el modificador "const" únicamente tiene sentido si amplía la cobertura... y de la única forma en la que puede hacer esto es haciendo que la clase o variable sea de solo lectura.
PD, creo que correctamente seria asi el la sobrecarga de +?
Foo operator+(const Foo& f)
{
Foo b;
b.bar_ = this->bar_ + f.bar_;
return b;
}
Es una forma de implementarlo... ahora, si Foo tiene un constructor que permite inicializar "bar_", es un poco más eficiente llamar a dicho constructor:
Foo operator+(const Foo& f) const
{
return Foo{ bar_ + f.bar_ };
}
Por cierto, nota el "const" de la función... los operadores que no tienen el igual no deberían modificar la instancia actual y deberían, por tanto, ser "const". Puede parecer una tontería, pero ya has visto que si un miembro no tiene el modificador "const" no puedes usarlo en una función "const".
Y tambien, + tendria que devolver objeto nuevo mientras que += referencia al objeto?
A ver, el operador "+" tiene que devolver un objeto nuevo porque, como te he comentado antes, este operador no debe modificar la instancia actual. Crear un objeto nuevo responde a la necesidad de devolver el resultado en un objeto que no sea el actual.
El operador "+=" si que tiene que modificar la instancia actual y, dado que al finalizar la función la instancia actual tendrá el valor bueno, suele ser más eficiente devolver una referencia que crear un objeto nuevo basado en el valor actual.
Espero haberte resuelto las dudas.
Un saludo.