Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if constexpr(condition) as compile-time conditional

I want to use a constexpr bool (useF in the example below) to enable a feature in the following code. Here, calling A::f(). Additionally, I want to be the alias-template (a) to be void in the case I switch off the feature.

I tried to use a constexpr if statement, but the body is still being instantiated, which causes a compile error. If I use a wrapper template (X), the body is being discarded as I'd expected, but that seems ugly to me. Are there any other ways to do this?

constexpr bool useF = false;

struct A {
    static void f() {}
};

using a = std::conditional<useF, A, void>::type;

template<typename L>
struct X {
    static void h() {
        if constexpr(std::is_same<L, A>::value) {
            L::f(); // not instantiated, no error
        }
    }
};

int main() {
    if constexpr(useF) {
        a::f(); // error!?
    }

    X<a>::h();
}

I am using g++-7.0.1 with -std=c++17

like image 666
wimalopaan Avatar asked Apr 19 '17 12:04

wimalopaan


People also ask

Does constexpr compile time?

constexpr indicates that the value, or return value, is constant and, where possible, is computed at compile time.

Is constexpr always evaluated at compile time?

A constexpr function that is eligible to be evaluated at compile-time will only be evaluated at compile-time if the return value is used where a constant expression is required. Otherwise, compile-time evaluation is not guaranteed.

What is if constexpr in C++?

In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool (until C++23)an expression contextually converted to bool, where the conversion is a constant expression (since C++23).

Can std :: function be constexpr?

Constexpr constructors are permitted for classes that aren't literal types. For example, the default constructor of std::unique_ptr is constexpr, allowing constant initialization.


1 Answers

if constexpr is only for templates. From [stmt.if]:

If the if statement is of the form if constexpr, the value of the condition shall be a contextually converted constant expression of type bool (5.20); this form is called a constexpr if statement. If the value of the converted condition is false, the first substatement is a discarded statement, otherwise the second substatement, if present, is a discarded statement. During the instantation of an enclosing templated entity (Clause 14), if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.

Within X, the constexpr if statement will prevent the otherwise ill-formed statement from being instantiated. That is the goal of this language feature. But outside of templates, there's no such equivalent gain.

like image 153
Barry Avatar answered Sep 28 '22 00:09

Barry