Reputation: 1700
I read this article. check if member exists using enable_if I modified the code of Johanness Schaub like this.
//////////////////////////////////////////////////////////////////////////
struct NormalChecker {
struct general_ {};
struct special_ : general_ {};
template<typename> struct int_ { typedef int type; };
template<typename Lhs>
void modify(Lhs &&lhs) {
cout << "modify\r\n";
modifyNormal(lhs, special_());
}
template<typename Lhs, typename int_<decltype(Lhs::normal)>::type = 0>
void modifyNormal(Lhs &&lhs, special_) {
cout << "modifyNormal with normal\r\n";
}
template<typename Lhs>
void modifyNormal(Lhs &&lhs, general_) {
cout << "modifyNormal without normal\r\n";
}
};
struct DataWithNormal {
int normal;
};
struct DataWithoutNormal {
};
int main() {
DataWithNormal with_normal;
DataWithoutNormal without_normal;
NormalChecker normalCheckerWithNormal;
normalCheckerWithNormal.modify(with_normal);
NormalChecker normalCheckerWithoutNormal;
normalCheckerWithoutNormal.modify(without_normal);
return 0;
}
But, it just says "modifyNormal without normal" twice. What am I missed?
Upvotes: 0
Views: 116
Reputation: 61920
Lhs
is deduced to be a reference type in your example, specifically DataWithNormal&
. Reference types don't have a nested normal
. One way to get around this is to check Lhs
when references are stripped:
decltype(std::remove_reference<Lhs>::type::normal)
Lifting Igor's comment, you can also pretend you have an object, since accessing a member of an object works even with a reference:
decltype(std::declval<Lhs>().normal)
Upvotes: 3