Consider the following snippet:
struct test1 {
static constexpr int get() {
return 1;
}
};
struct test2 {
constexpr int get() const {
return 1;
}
};
template <class T>
int get(T&& t) {
if constexpr (t.get() == 1) {
return 1;
}
return 2;
}
int main() {
return get(test1{}) + get(test2{});
}
When trying to compile with GCC-11.1 (-std=c++2a), get template successfully compiles with test1, but not with test2. The only difference between them is fact that test2::get is static.
Obviously, it does not compile with test2, because t parameter is not a "core constant expression", as per 7.7 expr.const(5.13):
An expression e is a core constant expression unless the evaluation of e, following the rules of the abstract machine, would evaluate one of the following expressions:
- an id-expression that refers to a variable or data member of reference type unless the reference has a preceding initialization...
The question is why it does compile, when the function being accessed via the very same reference is static. Isn't the refence "evaluated" in this case? Is it a GCC bug or there's some wording in the Standard that allows it?