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.

Reply via email to