One thing that's important to realize is that standard runtimes are commonly treated as any other code or library. How compiled code is linked and loaded depends a lot on the platform. .net is very different from c++.
Basically functions have at least three major ways of showing up inside of your binary:
This when a function is kept inside of a dynamically loaded library and is the case for many of the functions you'd get through windows.h as you said. Identifying these are generally easy as they're functionally separated and named either through their string name, decorated or undecorated, or through ordinal. Most disassemblers should handle dynamically linked standard functions without issues. This is the most common default for various compiler, runtime and platform options. This depends on the compiler being able to move the function to a separate compilation unit, which is commonly not the case with many templates in C++. Calling conventions are respected and prologue and epilogue are present.
Statically linked and not inlined
This is when a function is included inside of your binary but is functionally separate from other functions. This can be identified using a set of signatures of some form. IDA uses FLIRT signatures. Something like bindiff uses a more varied and complex approach to comparing functions, for instance using flow graph analysis. Usually parameters are passed according to calling convention unless the binary is built with link time optimization in which case the compiler is free to pass arguments in any order it feels like. If you're lucky the binary contains debug information which could allow for significant recovery of function names and parameters.
Statically linked and inlined
This is when a function is included inside of your binary and is not functionally separate from other functions. This generally happens when a function is small enough that the overhead to do a function call is expensive enough to warrant repeating the same function in the calling function or if the function is only called in very few locations, usually once, in the binary. This means that the disassembler has very little information to know that this was originally a separate function and debug information will not help much with recovery of these functions. There will be no function prologue or epilogue. Opcodes can be heavily rearranged/ The only tool I'm aware of that does very limited recovery of this sort of function is Hex-Rays decompiler, not diassembler. I've seen binaries with link time optimization where a function ends up being a massive result of hundreds of nested inlined functions, resulting in a function with thousands of branches. Separating them back out into their original functions would have been a very useful operation to have.
There is no solution that solves all the cases mentioned above. Hex-Rays IDA combined with their decompiler and BinDiff probably provides the most complete solution I know of. On very reflective platforms such as .net, java or python this isn't much of an issue.