https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96204
Bug ID: 96204 Summary: gcc complains about private member access in SFINAE context Product: gcc Version: 10.1.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: lts-rudolph at gmx dot de Target Milestone: --- gcc complains with following error in the example code: main.cpp:59:72: error: 'void Child::setAttr(int)' is private within this context 59 | struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr(1))>> { | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ main.cpp:85:14: note: declared private here 85 | void setAttr(int x) { | ^~~~~~~ main.cpp:59:72: error: 'void Child::setAttr(int)' is private within this context 59 | struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr(1))>> { | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ main.cpp:85:14: note: declared private here 85 | void setAttr(int x) { | ^~~~~~~ main.cpp:59:72: error: 'void Child::setAttr(int)' is private within this context 59 | struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr(1))>> { | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~ main.cpp:85:14: note: declared private here 85 | void setAttr(int x) { Full code example: --------------- template <typename, typename = void_t<>> struct has_set_attr_method { static constexpr bool value = false; }; template <typename T> struct has_set_attr_method<T, void_t<decltype(std::declval<T>().setAttr(1))>> { static constexpr bool value = true; }; struct Parent { public: template<typename T> static void create() { auto obj = T::create(); if constexpr(has_set_attr_method<T>::value) { cout << "has setAttr" << endl; } else { cout << "no setAttr" << endl; } } }; struct Child : public Parent { public: friend class Parent; static auto create() { return Child(); } private: void setAttr(int x) { } }; int main(int argc, char const *argv[]) { Parent::create<Child>(); return 0; } --------------- Interestingly the failure depends on "friend" declaration inside "Child".