Recently, after playing around with the C 20 feature of being able to pass class types in non-type template parameters (P0732R2), I've encountered something rather strange.
Consider the following code:
template <typename T>
struct abc {
T p;
consteval abc(T p) : p(p) { }
consteval operator decltype(p)() const {
return p;
}
};
template <abc obj>
consteval auto do_something1() {
return obj();
}
template <auto obj>
consteval auto do_something2() {
return obj();
}
constexpr auto fun() {
return true;
}
int main() {
static_assert(do_something1<&fun>()); // OK in Clang, fails in GCC
static_assert(do_something2<&fun>()); // OK in both GCC and Clang
}
This appears to work as intended with clang however GCC fails to compile this and gives an error saying that fun
is not a valid template argument.
However, this answer says that function pointers should be valid template arguments as per the C standard.
Which compiler is correct here?
Also, weirdly enough, the same code appears to work on both compilers when modified to work with member functions for some reason.
Note: Something that might be useful to note is that according to this page, GCC's support for P0732R2 is complete while Clang's is still in a partial/experimental stage. So, does this mean that GCC is correct and passing of function pointers through class types in non-type template parameters shouldn't be possible, or am I missing something here?
CodePudding user response:
Which compiler is correct here?
Clang is correct, the code as written is valid.
GCC not handling that specific case is a known issue.