The first problem is: there is no diamond problem. Everything works as designed. Using virtual inheritance means you have to walk back in old sources and find the first inheritance to the same class and make the virtual, too.
So: no real solution, as such sources usually are not under your control.
And in cases where you indeed want to inherit several times, without using 'virtual' you still have no option to 'access' the 'parts' you intentionally inherited multiple times.
The solution would be so simple:
class Derived : Base A, Base B {} and now you could write Derived::A and Derived::B to access the 'parts' if you needed to. No idea why the designers of C++ are against this solution.
So in our days the internet is full with advices not to use MI in C++, however there are plenty and elegant uses for it.
E.g. you know you have certain objects which you want to hold ALWAYS in at least two linked lists.
An easy way to do that is to have a LinkededList template that has as template argument an integer or an enum.
Now you let inherit your class twice from that List with two different arguments (constants like 'parent=0' and 'siblings=1'). Now every object has a linked list going up to the parent and one covering its siblings 'build in'.
I did not invent that 'idiom', Jiri Soukoup did.
Anyway, in combinations with templates MI is a killer feature. I'm really pissed that Java/C# has neither templates (and no, generics are something completely different) nor MI, just because some idiots spread the mantra "MI is bad" in the early 1990s ...