I think you have a bit of a misunderstanding of CRTP. It is not a plug in replacement for virtual dispatch. In your case, IBridge has no virtual dispatch, so calling IBridge->LoadDriver will always give you the default base class implementation, regardless of the underlying derived class. If you want a generic interface, you need some kind of virtual dispatch. CRTP is just a way of avoiding virtual dispatch in cases where it is not necessary, for example when a base class member function calls in to other virtual functions.
If you want to avoid virtual dispatch completely in you case, you can not completely decouple the client from the Bridge, you would need to template Client on Bridge which doesn't really give you any advantage over just templating on Derived.
Here's a shot at doing what you want. It assumed that you pass some generic pointer through IBridge, which Bridge uses CRTP to interpret and pass down to BridgeImpl. Obviously, you've abandoned all hope of type safety on the arguments at this point.
class IBridge {
virtual void LoadDriver(void *) = 0;
};
template <typename Impl>
class Bridge : public IBridge {
void LoadDriver(void * v) override {
static_cast<Impl*>(this)->LoadDriverImpl(*static_cast<Impl::arg_type *>(v));
}
};
class BridgeImpl : public Bridge<BridgeImpl> {
typedef std::string arg_type;
void LoadDriverImpl(const std::string & s){ /*...*/ }
};