I have a trait to determine the class of a member function pointer.
In GCC12, it works for both const and const noexcept function pointers.
In GCC13, it no longer works. Clang 16 and MSVC agree with GCC12. If I add a noexcept specialisation, it fixes GCC12, and breaks GCC12/Clang/MSVC.
Is this behaviour specified in the C++ Standard, or is this a GCC bug?
If this is expected behaviour, how can I support both GCC12 and GCC13?
#include <type_traits>
template <auto>
struct get_class;
template <typename Ret, typename Klass, typename... Args, Ret (Klass::*FN)(Args...) const>
struct get_class<FN> : public std::type_identity<Klass>
{};
// Uncomment this to fix GCC13, and break everyone else...
//template <typename Ret, typename Klass, typename... Args, Ret (Klass::*FN)(Args...) const noexcept>
//struct get_class<FN> : public std::type_identity<Klass>
//{};
class MyClass {
public:
int func1() const noexcept {return 0;}
int func2() const {return 0;}
};
int main(){
[[maybe_unused]]get_class<&MyClass::func1>::type x = MyClass{};
[[maybe_unused]]get_class<&MyClass::func2>::type y = MyClass{};
}
Live example: https://godbolt.org/z/YGv8hxPWd
Based on this:
noexcept specifier (since C++11) - cppreference.com
So in C++17 when
noexceptis part of function type, then template specialization should take it into account. So looks like gcc 13 is right and other compilers are wrong.I've also found something like this: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4533.html
On other hand there is code compatibility issues, so I would not be surprised this could be controlled by some compilation flag (and different default behavior was selected). I would recommend review compiler documentation about this.
Disclaimer I'm not language lawyer so maybe someone can provide better information.