@Caleth I'm interested to understand more about your comment
There's also specialisations, but the general advice is to never define specialisations of function templates, because of the interaction with overload resolution.
In addition, you constrained the compiler instantiation of the two versions of the do_something function.
You did this using
template<typename Stringable, std::enable_if_t<std::is_same_v<decltype(std::declval<Stringable>().to_string()), std::string>, int> = 0>
Can you tell us more about why? I would guess this is related to your first comment never define specialisations of function templates ?