What to do if you end up in the following situation
The intent here is that b and c can be substitutable for a. The client creates a bar through foo_1, which later may be passed back to foo_1 through the use_bar. The problem is that foo_1 only accepts bar_1 and foo_2 only accepts bar_2. Thus, this design is not type safe.
It does not matter that foo acts as an abstract factory as well as a user of bar objects, since concrete bars belong to a specific implementation.
One solution is to bind the foo to the created bar and add an abstract member function use() to the bar interface, but then it is not possible to use the bar with a different foo of the same kind.
Another option would be to let the client code be a template. This solves the issue, but in this context, I prefer runtime binding, in order to make the code less verbose.

use_bar(bar)should not be part of the foo interface but instead distinct methods on foo_1 and foo_2 taking bar_1 or bar_2 as parameter.use_bar(bar)have been over-abstracted since bar_1 and bar_2 cant actually be substituted.use_bar(IBar)signature that you have right now, and raise an exception if the wrong concrete type is passed.