3 ms·
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 bas
by cfallin 11y ago
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/protobuf/arena.h#L559 https://github.com/google/protobuf/blob/master/src/google/pr...
- weland 11y agoThat's neat! Thank you for the explanation!