Inline is required when the function is inside the header but not within the class declaration and the header is used in multiple compilation units. Without the inline keyword the function will be multiply defined and will not compile.
Also a static inline function is a special case that is not quite what you asked. That use of "static inline" has its own meaning and is significant when you see it used.
Beyond that, the inline keyword for non-static functions is just a hint. It is a request that the compiler is free to ignore, asking to replace the body of the function into the code that calls it.
Over the decades that the inline keyword has been in use compilers have come a long way. The optimizers have become extremely good at detecting functions that should be made inline and automatically moving them inline. This is why for many compilers the inline keyword is unnecessary except for the one required case of functions in a header.
Other times the optimizer may detect that inlining a function marked inline would result in worse performance so they reject it. Sometimes they may even include the function one time and reject the same function elsewhere based on contextual information.
There are compiler-specific ways to tell the compiler that you know better than it and it should inline the function even when it normally wouldn't want to. Those are __forceinline and __declspec(noinline) on the MSVC and related compilers, or __attribute__((always_inline)) and __attribute__((noinline)), or compiler-specific codes for different compiler familes. Usually it is a bad idea to override the compiler unless you have actual profiling data that proves the result.
On modern systems unless you have actual values from profilers, map files, and disassembly which demonstrates a function should or should not be inlined, it is best to let the optimizer figure it out for you.