Having problems with SFINAE. I need to determine if a type has an operator-member-function defined independently of its return type. Example.
This class is in test. It defines an operator β () with return type X *. Thus, I will not know that the "X" hardcodes for this.
template <class X>
class PointerX
{
...
X* operator->() const;
...
}
This class is trying to determine if the method passed to T has operator-> define; regardless of type of operator-> return.
template<typename T>
struct HasOperatorMemberAccessor
{
template <typename R, typename C> static R GetReturnType( R ( C::*)()const);
template<typename U, typename R, R(U::*)()const> struct SFINAE{};
template<typename U> static char Test(SFINAE<U, decltype( GetReturnType(&U::operator->)), &U::operator-> >*);
template<typename U> static uint Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};
This class is the same as above, except that the type operator-> return must be "Object".
template<typename T>
struct HasOperatorMemberAccessorOBJECT
{
template <typename R, typename C> static R GetReturnType( R ( C::*)()const);
template<typename U, typename R, R(U::*)()const> struct SFINAE{};
template<typename U> static char Test(SFINAE<U, Object*, &U::operator-> >*);
template<typename U> static uint Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};
Results:
void main()
{
HasOperatorMemberAccessor<PointerX<Object>>::Test<PointerX<Object>>(0); // fails ::value is false; Test => Test(...)
HasOperatorMemberAccessorOBJECT<PointerX<Object>>::Test<PointerX<Object>>(0); // works! ::value is true; Test => Test(SFINAE<>*)
}
HasOperatorMemberAccessor PointX " β () const".
Test (...).
HasOperatorMemberAccessorOBJECT PointX " β () const".
, Test (SFINAE *).
"Object operator β () const"; , , Test (SFINAE *); HasOperatorMemberAccessor > :: .
HasOperatorMemberAccessor HasOperatorMemberAccessorOBJECT , HasOperatorMemberAccessorOBJECT typename R, ,
, , "decltype (GetReturnType (& U:: operator- > ))" . . :
decltype( GetReturnType(&U::operator->) )
typename decltype( GetReturnType(&U::operator->))
decltype( ((U*)nullptr)->operator->() )
typename decltype( ((U*)nullptr)->operator->() )
, ? MSV++ 10.0.