Could someone please help me understand how this is different to conflicting definitions of functions that are not defined in classes (which do cause warnings/errors).
The difference is that function definitions inside a class are implicitly nominally inline, which inhibits the compiler warnings if the function's encountered again. That doesn't mean the compiler has to inline them - it may decide using whatever heuristics not to bother, or it may simple never inline at some optimisation levels. Anyway, if you link code that's seen different definitions of nominally inline non-member functions you have exactly the same problem.
See 3.2/6
There can be more than one definition of a class type ... in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements.
— each definition of D shall consist of the same sequence of tokens; and
[others requirements]
More generally, you should have put your code into anonymous namespaces... they're designed to prevent cross-translation-unit problems of this kind.