The core code provides default template implementations that pass through to member functions of the custom type. This allows most of the functionality to be centralized in the new custom type, while still allowing for non-member overloads if you choose to do it that way.