While attempting to create a trait to check whether the class field is publicly available I've created a code:
#include <type_traits>
#include <utility>
template <class T, class = void>
struct does_not_have_foo: std::true_type {};
template <class T>
struct does_not_have_foo<T, decltype(std::declval<T>().foo, void())>: std::false_type {};
class Foo {
int foo;
};
int main() {
static_assert(does_not_have_foo<Foo>::value);
}
But it appeared to failed to compile in [gcc] ([clang] seemed to be more permissive here) with an error:
prog.cc:8:56: error: 'int Foo::foo' is private within this context
I dug up for some older code of mine doing something similar which boils down to following:
template <class T>
auto does_not_have_foo(T t) -> decltype(t.foo, std::false_type()) {
return {};
}
std::true_type does_not_have_foo(...) { return {}; }
class Foo {
int foo;
};
int main() {
static_assert(decltype(does_not_have_foo(Foo{}))::value);
}
It looked like it done its job in both [gcc] just as well as in [clang]. But when I was looking for a reason of gcc failure I found the question which suggests that every attempt to use of private field of the class is ill-formed and as such even the second code should be avoided. Am I over-interpreting the question or is the second code really the language abuse?