Yes. In fact, the usual mechanism for doing so is referred to as tag dispatch. For example, an algorithm can take an arbitrary Iterator type, and select between a correct-but-slow algorithm for weak iterators like forward iterators, and a fast algorithm for strong iterators like random-access iterators. The easiest way to achieve this is to call a helper function and pass a tag object whose type is iterator_traits<Iterator>::iterator_category, which might be forward_iterator_tag or random_access_iterator_tag. The helper function is then overloaded on those tags, achieving the effect of a compile-time if. Everything optimizes away (the compiler is very good at noticing do-nothing tag objects).
Expression SFINAE offers the ability to detect more properties of things, like is_callable or has_member_function_meow. This can then be used in tag dispatch, or other mechanisms (SFINAE can be used directly to dispatch, but it's a more lengthy explanation).