Well, let's first demolish some of your assumptions:
- One of the advantages of header-only libraries for C++ is that they do not need to be compiled separately.
Compiling things separately means potentially not having to recompile everything if only a part changes.
So, a disadvantage instead of an advantage.
- In C and C++ inline makes sense only if the function is defined in a header file*.
Yes, the only effect
inline has left is the exception to the one-definition-rule.
Woe unto you if those definitions are different in any way though.
So, if a function is internal to a compilation-unit, mark it
static. That also makes inlining more likely, as the function needs to be available in order to inline it.
Still, take a look at link-time-optimization, as supported by at least MSVC++, gcc and clang.
- Traditionally, in C, .c/.h layout has been used, where the header represents the minimal public interface of the translation unit. Similarly, .cpp/hpp.
Well, only presenting the minimal interface is certainly one of the goals, to achieve higher API and ABI stability, and to minimize compilation times.
Especially C++ classes aren't really geared to that though, as all the private bits leak into the header, as do the protected ones whether you want to derive from it or not.
The design-pattern PIMPL is for reducing such details.
The part where separating interface and implementation completely fails in C++ is templates though.
The committee tried to do something with exported templates, but that has been abandoned as too complicated and not really working.
Now, they are working on a proper module system, though it's slow going. That severely reduce compile-times, and should also increase API and ABI stability by decreasing their surface.
Are header-only libraries generally more efficient code- and execution time wise than the traditional layout? If so, is this because of extensive inlining or other optimizations?
Header-only libraries can be more efficient in code-size and execution-time, though that depends on whether the library is shared, how much of it is used, in what ways, and whether inlining proves a decisive win in that specific case.
And the reason inlining is so important for optimization isn't because inlining itself is such a great boost, but due to the opportunities for constant-propagation and further optimization it opens.