Search code examples
c++templatesc++11sfinaestatic-assert

When to use `static_assert` instead of SFINAE?


I have been using (and seen used) static_assert to flag undesired values of template parameter values. However, for all cases I came across it seems better and more elegant to disable those undesired values via SFINAE.

For example:

template<typename T,
         class = std::enable_if<std::is_floating_point<T>::value>::type>
struct Foo { ... };

instead of:

template<typename T>
struct Foo
{
    static_assert(std::is_floating_point<T>::value,
                  "Foo<T>: T must be floating point :-(");
    ...
};

So my question: when should I use static_assert instead of SFINAE and why?

EDIT:

I think what I've learned so far is the following:

1. SFINAE is a versatile and powerful but potentially very complicated tool that can be used for many tasks, including function overload resolution (which some seem to regard as its only purpose).

2. SFINAE can be used in a relatively simple way wherever static_assert can, except that it appears in the declaration (of a class or function) rather than its definition (or is is possible to insert a static_assert into, say, a class forward declaration?). That makes more verbatim and hence clearer code. However, because SFINAE is complicated, it tends to be harder to get right than a simple static_assert.

3. On the other hand static_assert has the benefit of a clearer compiler error message, which some seem to regard as the main purpose of both.


Solution

  • I think static_assert is the right choice if you want to enforce that T is a floating point type. This method states your intent more clearly than the SFINAE solution.