Why do I get "use of undeclared identifier" even when using constexr if?

1.1k Views Asked by At

play with the code.

template<typename T>
T f() {
    if constexpr (std::is_same<T, int>::value) {
        T t = 10;
    }else {
        T t;
    }
    return t;
}

My understanding of the above code is that the body of f will either be

int t = 10; 
return t;

or

T t = // some default value for T 
return t;

depending on T. In both there will be an identifier called t. Why does the compiler still complain about use of undeclared identifier 't'?.

Does the compiler check for undeclared identifiers before it resolves constexpr statements?

2

There are 2 best solutions below

0
On BEST ANSWER

My understanding of the above code is that the body of f will either be

int t = 10; 
return t;

or

T t = // some default value for T 
return t;

No. A more valid comparison is that it will be either, for the true branch:

{
    int t = 10;
} // end of scope for 't'
return t;  // 

or, for the else branch:

{
    T t;
} // end of scope for 't'
return t;

Meaning the t in the return statement refers to an entity that does not exist (in that scope).

0
On

if constexpr is not a macro; do not treat it as such. It is a standard C++ construct and it's grammar works like most C++ constructs. Indeed, its grammar works like if (which is why it's spelled "if constexpr"). While if constexpr has the ability to discard the statements within one of its blocks in certain situations, this is basically the only special thing about it grammatically.

Curly braces define the scope of names. Names declared within the curly braces inside a function aren't available outside of them. That didn't change just because you wrote constexpr after the if.