Probleme mit SFINAE. Ich muss in der Lage sein zu bestimmen, ob ein Typ einen Mitgliedsfunktionsoperator definiert hat, unabhängig von seinem Rückgabetyp. Beispiel folgt.SFINAE - Es wird versucht, festzustellen, ob der Schablonentyp eine Mitgliedsfunktion mit der Rückgabetyp 'Variable' hat
Diese Klasse im Tester. Es definiert operator ->() mit einem Rückgabetyp von X *. Ich werde also nicht wissen, was "X" ist, um es überall zu kodieren.
template <class X>
class PointerX
{
...
X* operator->() const;
...
}
Zu dieser Klasse versucht wenn die in T weitergegeben bestimmt hat ein Verfahren operator-> definiert sind; unabhängig davon, welcher Operator-> Rückgabetyp ist.
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);
};
Diese Klasse ist die gleiche wie oben, nur dass operator-> return type 'Object' sein muss.
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-> >*); // only change is we hardcoded Object as return type.
template<typename U> static uint Test(...);
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
};
Ergebnisse:
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 konnte PointX der Member-Funktion "Objekt Operator ->() const" finden. So verwendet es Test generische Version Test (...).
HasOperatorMemberAccessorOBJECT konnte jedoch den "Object Operator ->() const" von PointX finden. So verwendet es Test spezialisierte Version Test (SFINAE *).
Beide sollten in der Lage sein, den "Object operator ->() const" -Methode zu finden; und daher sollten beide die Testversion von Test (SFINAE *) verwenden; und daher sollte HasOperatorMemberAccessor> :: value für beide wahr sein.
Der einzige Unterschied zwischen HasOperatorMemberAccessor und HasOperatorMemberAccessorOBJECT ist, dass HasOperatorMemberAccessorOBJECT die Typnamen R hat, das Objekt fest einprogrammiert zu
So ist das Problem, dass "decltype (GetReturnType (& U :: operator->))" Rückkehr Objekt ist nicht korrekt. Ich habe eine Reihe verschiedener Genehmigungen ausprobiert, um den Rückgabetyp zu ermitteln. Sie gehen wie folgt:
decltype(GetReturnType(&U::operator->))
typename decltype(GetReturnType(&U::operator->))
decltype(((U*)nullptr)->operator->())
typename decltype(((U*)nullptr)->operator->())
Keine Arbeit, warum? Ich verwende MSVC++ 10.0.
Eine Sache, die das Auge auffällt, ist, dass 'PointerX :: operator->' 'zurück bool *', 'nicht bool'. –
Der Typ von X in PointerX spielt keine Rolle, was HasOperatorMemberAccessor betrifft. Ich habe versucht, mein Problem zu verallgemeinern, indem ich dem Beispiel nicht viele überflüssige Objekte hinzugefügt habe. Wenn es zu verwirrend ist, werde ich bool in string umwandeln. –
Lassen Sie es mich erneut versuchen.PointerX