Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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".

like image 215
Trevor Hickey Avatar asked Jul 08 '16 04:07

Trevor Hickey


People also ask

Can constexpr use if?

constexpr if can be used to replace several tricks that were already done: SFINAE technique to remove not matching function overrides from the overload set. you might want to look at places with C++14's std::enable_if - that should be easily replaced by constexpr if . Tag dispatch.

Is if constexpr always compile time?

A constexpr variable must be initialized at compile time. All constexpr variables are const . A variable can be declared with constexpr , when it has a literal type and is initialized.

What is a constexpr function?

A constexpr function is a function that can be invoked within a constant expression. A constexpr function must satisfy the following conditions: It is not virtual. Its return type is a literal type. Each of its parameters must be of a literal type.

What is false constexpr?

In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool. If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.


1 Answers

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.

like image 56
Nicol Bolas Avatar answered Sep 21 '22 13:09

Nicol Bolas