Search code examples
c++c++17constexprsfinaeoverload-resolution

Is "constexpr if" considered SFINAE?


How is constexpr if and SFINAE related?
Does the compiler employ SFINAE when evaluating "constexpr if" expressions?

I think "constexpr if" is using SFINAE.
It's substituting in the conditional block, but not erroring out when it can't.

On the other hand, SFINAE is defined as a rule for overload resolution of function templates, and I suppose you are already in a function when "constexpr if" is being evaluated.

The compiler must be generating out multiple functions for the different paths of constexpr if depending on how the function is called though. So maybe it is using overload resolution.

The accepted proposal makes no mention of "SFINAE" or "overload resolution".
So I'm curious if either concept is applicable in regards to "constexpr if".


Solution

  • SFINAE, at its core is this: you write certain code that triggers an illegal thing in C++. But because you put that code in a certain place, it doesn't cause a compile error. It just causes the definition that contained that code to disappear. You can therefore use conditional tests that when true result in legal C++ syntax and when false do not (vis-a-vis std::enable_if).

    if constexpr has nothing to do with SFINAE. if constexpr is merely evaluating a constant expression, then executing one set of statements or the other. The only "SFINAE"-esque part is that any statements in the unexecuted part of the condition effectively don't exist when used in a template (and when not in a template, have as few effects as it is possible to have). So it's possible to do something like this:

    template<typename T>
    void Foo()
    {
        if constexpr(!is_same_v<T, void>)
        {
            T t;
        }
    }
    

    The code within the if statement would have been illegal if T were void. However, because the condition is there to make the potentially illegal code go away, it is legal to call Foo<void>.

    Does the compiler employ SFINAE when evaluating "constexpr if" expressions?

    It could, but seriously, why would it? It's the compiler; it doesn't have to use enable_if gymnastics or C++ template arcana to make statements disappear. It just evaluates a constant expression, and makes statements go away based on that.

    It's substituting in the conditional block, but not erroring out when it can't.

    No, the condition has to be a legal C++ constant expression, whether it evaluates to true or false. The unexecuted block may have illegal syntax in it. But the condition itself must always be legal.