https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90880
Bug ID: 90880 Summary: compile error instead of SFINAE with non-public member variables Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: federico.kircheis at gmail dot com Target Milestone: --- Hello, I searched for bugs related to SFINAE, and I do not think that this one has already reported: ---- #include <type_traits> #include <cstdio> template <typename T, typename = void> struct status : std::false_type{}; template <typename T> struct status<T, decltype(T::member, void())> : std::true_type {}; struct s1{int member;}; struct s2{int _member;}; class c1{int member;}; class c2{int _member;}; int main(){ static_assert(status<s1>::value, "has member"); static_assert(!status<s2>::value, "has no member"); (void) status<c1>::value; //static_assert(status<c1>::value, "has member"); static_assert(!status<c2>::value, "has no member"); } ----- This code compiles fine with msvc and clang, but with g++ it triggers following compiler error: -- bug.cpp: In substitution of ‘template<class T> struct status<T, decltype ((T::member, void()))> [with T = c1]’: bug.cpp:15:19: required from here bug.cpp:6:58: error: ‘int c1::member’ is private within this context template <typename T> struct status<T, decltype(T::member, void())> : std::true_type {}; ~~~~~~~~~^~~~~~~~ bug.cpp:10:14: note: declared private here class c1{int member;}; ^~~~~~ bug.cpp: In instantiation of ‘struct status<c1>’: bug.cpp:15:19: required from here bug.cpp:6:58: error: ‘int c1::member’ is private within this context template <typename T> struct status<T, decltype(T::member, void())> : std::true_type {}; ~~~~~~~~~^~~~~~~~ bug.cpp:10:14: note: declared private here class c1{int member;}; ^~~~~~ bug.cpp:6:58: error: ‘int c1::member’ is private within this context template <typename T> struct status<T, decltype(T::member, void())> : std::true_type {}; ~~~~~~~~~^~~~~~~~ bug.cpp:10:14: note: declared private here class c1{int member;}; -- While the error message could be correct (more on that later), the issue is that because of SFINAE, this should never be compile-error (just like for `s2` and `c2`). I've commented `static_assert(status<c1>::value, "has member");` out, because clang++ compiles `status<c1>::value` to false, while msvc to true. I'm not 100% sure which of the compiler is correct, but `status<c1>::value` should definitively compile.