Constexpr variable captured inside lambda loses its constexpr-ness

How to work around it while keep the compile-time guarantee?

Marking the constexpr bool as static serves as a work around.

See Demo

Alternately, you can use the condition in the if constexpr instead of assigning it to a bool. Like below:

if constexpr(std::is_same_v<T,int>)

See Demo

Note that there have been bugs raised for MSVC regarding constexpr with respect to lambda expressions.
One such is: problems with capturing constexpr in lambda
and another is: if constexpr in lambda


Gcc is right. b (as constexpr variable) doesn't need to be captured in fact.

A lambda expression can read the value of a variable without capturing it if the variable

  • is constexpr and has no mutable members.

GCC LIVE

It seems if making b static then MSVC could access b without capturing.

template<class T> void f(){
    constexpr static bool b=std::is_same_v<T,int>;
    auto func_x=[](){
        if constexpr(b){
        }else{
        }
    };
    func_x();
}

MSVC LIVE

And

How to work around it while keep the compile-time guarantee?

We can't keep the constexpr-ness for the captured variables. They become non-static data members of the lambda closure type and non-static data members can't be constexpr.