https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104678
Bug ID: 104678 Summary: pointer to member cannot be passed as template argument after derived/base cast Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: schaumb at gmail dot com Target Milestone: --- If I has a pointer to member value, when I static cast to derived member pointer then back to the original, it cannot be used as a template argument. struct B { int m; }; struct D : B {}; template<int B::*> struct X; constexpr int B::* memptr = &B::m; constexpr int B::* same_p = static_cast<int B::*>(static_cast<int D::*>(&B::m)); static_assert(memptr == same_p, ""); // OK // static_assert(std::is_corresponding_member(memptr, same_p)); // OK using Good = X<memptr>; // OK using Bad = X<same_p>; // error fails with the following message: error: '0' is not a valid template argument for type 'int B::*' note: it must be a pointer-to-member of the form '&X::Y as you can see here: https://godbolt.org/z/oa3jY6c41 The C++20 ISO says: § 7.3.12, 2: A prvalue of type “pointer to member of B of type cv T”, where B is a class type, can be converted to a prvalue of type “pointer to member of D of type cv T”, where D is a complete class derived (11.7) from B. The result of the conversion refers to the same member as the pointer to member before the conversion took place, but it refers to the base class member as if it were a member of the derived class. The result refers to the member in D’s instance of B. The result is the same as if indirecting through the pointer to member of B with the B subobject of D. § 7.6.1.7, 12: A prvalue of type “pointer to member of D of type cv1 T” can be converted to a prvalue of type “pointer to member of B of type cv2 T”, where D is a complete class type and B is a base class (11.7) of D, if cv2 is the same cv-qualification as, or greater cv-qualification than, cv1. If class B contains the original member, or is a base or derived class of the class containing the original member, the resulting pointer to member points to the original member. - All gcc version affected - The problem is system independent - The gcc compile options are not related - command line: see at godbolt, g++ main.cpp - error message: see above