//User types
struct field_t{};
struct other_t{};
struct StructT{other_t field;field_t other;};
//Implementation detail
template<typename T,typename FIELD_T>
struct type_has_field{
struct Fallback {FIELD_T field;};
struct Derived:T,Fallback{};
template<typename C, C> struct ChT;
template<typename C> static char (&f(ChT<FIELD_T Fallback::*, &C::field>*))[1];
static bool const value = sizeof(f<Derived>(0)) == 2;
};
//Experiment
static_assert(
false==type_has_field<StructT,field_t>::value,
"field_t StructT::field - should not exist"
);
int main(){return 0;}
Ly9Vc2VyIHR5cGVzCnN0cnVjdCBmaWVsZF90e307CnN0cnVjdCBvdGhlcl90e307CnN0cnVjdCBTdHJ1Y3RUe290aGVyX3QgZmllbGQ7ZmllbGRfdCBvdGhlcjt9OwovL0ltcGxlbWVudGF0aW9uIGRldGFpbAp0ZW1wbGF0ZTx0eXBlbmFtZSBULHR5cGVuYW1lIEZJRUxEX1Q+CnN0cnVjdCB0eXBlX2hhc19maWVsZHsKICBzdHJ1Y3QgRmFsbGJhY2sge0ZJRUxEX1QgZmllbGQ7fTsKICBzdHJ1Y3QgRGVyaXZlZDpULEZhbGxiYWNre307CiAgdGVtcGxhdGU8dHlwZW5hbWUgQywgQz4gc3RydWN0IENoVDsKICB0ZW1wbGF0ZTx0eXBlbmFtZSBDPiBzdGF0aWMgY2hhciAoJmYoQ2hUPEZJRUxEX1QgRmFsbGJhY2s6OiosICZDOjpmaWVsZD4qKSlbMV07CgogIHN0YXRpYyBib29sIGNvbnN0IHZhbHVlID0gc2l6ZW9mKGY8RGVyaXZlZD4oMCkpID09IDI7Cn07Ci8vRXhwZXJpbWVudAoKc3RhdGljX2Fzc2VydCgKICBmYWxzZT09dHlwZV9oYXNfZmllbGQ8U3RydWN0VCxmaWVsZF90Pjo6dmFsdWUsCiAgImZpZWxkX3QgU3RydWN0VDo6ZmllbGQgLSBzaG91bGQgbm90IGV4aXN0IgopOwoKaW50IG1haW4oKXtyZXR1cm4gMDt9
prog.cpp: In instantiation of ‘const bool type_has_field<StructT, field_t>::value’:
prog.cpp:18:43: required from here
prog.cpp:13:37: error: no matching function for call to ‘type_has_field<StructT, field_t>::f(int)’
static bool const value = sizeof(f<Derived>(0)) == 2;
^
prog.cpp:13:37: note: candidate is:
prog.cpp:11:38: note: template<class C> static char (& type_has_field<T, FIELD_T>::f(type_has_field<T, FIELD_T>::ChT<FIELD_T type_has_field<T, FIELD_T>::Fallback::*, (& C:: field)>*))[1] [with C = C; T = StructT; FIELD_T = field_t]
template<typename C> static char (&f(ChT<FIELD_T Fallback::*, &C::field>*))[1];
^
prog.cpp:11:38: note: template argument deduction/substitution failed:
prog.cpp: In substitution of ‘template<class C> static char (& type_has_field<T, FIELD_T>::f(type_has_field<T, FIELD_T>::ChT<FIELD_T type_has_field<T, FIELD_T>::Fallback::*, (& C:: field)>*))[1] [with C = C; T = StructT; FIELD_T = field_t] [with C = type_has_field<StructT, field_t>::Derived]’:
prog.cpp:13:37: required from ‘const bool type_has_field<StructT, field_t>::value’
prog.cpp:18:43: required from here
prog.cpp:11:65: error: reference to ‘type_has_field<StructT, field_t>::Derived::field’ is ambiguous
template<typename C> static char (&f(ChT<FIELD_T Fallback::*, &C::field>*))[1];
^
prog.cpp:8:28: note: candidates are: field_t type_has_field<StructT, field_t>::Fallback::field
struct Fallback {FIELD_T field;};
^
prog.cpp:4:24: note: other_t StructT::field
struct StructT{other_t field;field_t other;};
^