One example where I've found SFINAE useful is in using "type traits" to tag different classes, and then writing containers to handle the classes differently based on their tags (see [1]).
For example, in arena-allocation support for protobufs, we wanted to be able to skip a destructor call to a message object if the object used only arena-allocated storage (hence had no cleanup to do). So we added a "DestructorSkippable_" typedef to any class where this was true:
class MyObject {
private:
friend class Arena;
typedef void DestructorSkippable_;
// ...
};
And then the SFINAE use at the implementation linked below [1] can either register a destructor callback, or not, depending on the class (by providing two overrides to a function, one that takes a T::DestructorSkippable_* param and one that doesn't).The essential thing about this is that it's resolved at compile time, so there's zero overhead (not even a runtime conditional-check) in the destructor-skipped case. When optimizations are enabled, constant prop and dead-code elimination can completely remove a feature that's "disabled" by a certain type trait.
[1] https://github.com/google/protobuf/blob/master/src/google/pr...