Why should I avoid std::enable_if in function signatures

Put the hack in the template parameters.

The enable_if on template parameter approach has at least two advantages over the others:

  • readability: the enable_if use and the return/argument types are not merged together into one messy chunk of typename disambiguators and nested type accesses; even though the clutter of the disambiguator and nested type can be mitigated with alias templates, that would still merge two unrelated things together. The enable_if use is related to the template parameters not to the return types. Having them in the template parameters means they are closer to what matters;

  • universal applicability: constructors don’t have return types, and some operators cannot have extra arguments, so neither of the other two options can be applied everywhere. Putting enable_if in a template parameter works everywhere since you can only use SFINAE on templates anyway.

For me, the readability aspect is the big motivating factor in this choice.

Leave a Comment