"Was ist mit meiner SFINAE passiert?"
Ich bin neu im Schreiben von Vorlagen-Metaprogrammiercode (anstatt ihn nur zu lesen). Also habe ich Probleme mit Noobs. Eine davon ist in diesem Non-SO-Beitrag mit dem Namen ziemlich gut zusammengefasst"Was ist mit meiner SFINAE passiert?", die ich C ++ 11-ize wie folgt:
(Hinweis: Ich habe den Methoden unterschiedliche Namen gegeben, nur um bei der Fehlerdiagnose in diesem "Gedankenexperiment" - Beispiel zu helfen. Siehe@ R.MartinhoFernandes Notizen Warum würden Sie diesen Ansatz in der Praxis nicht für Nicht-Überladungen wählen?)
#include <type_traits>
using namespace std;
template <typename T>
struct Foo {
typename enable_if<is_pointer<T>::value, void>::type
valid_if_pointer(T) const { }
typename disable_if<is_pointer<T>::value, void>::type
valid_if_not_pointer(T) const { }
};
int main(int argc, char * argv[])
{
int someInt = 1020;
Foo<int*>().valid_if_pointer(&someInt);
Foo<int>().valid_if_not_pointer(304);
return 0;
}
@Alf sagt, was mit der SFINAE passiert ist, ist "Es war gar nicht da", und gibt einen Vorschlag, der kompiliert, aber die Funktionen anstelle der Klasse schabloniert. Das mag für einige Situationen richtig sein, aber nicht für alle.(Zum Beispiel: Ich versuche speziell, einen Container zu schreiben, der Typen enthalten kann, die möglicherweise kopierkonstruierbar sind oder nicht, und ich muss Methoden basierend darauf ein- und ausschalten.)
Um das Problem zu umgehen, habe ich einen Versuch unternommen ... der anscheinend korrekt funktioniert.
#include <type_traits>
using namespace std;
template <typename T>
struct FooPointerBase {
void valid_if_pointer(T) const { }
};
template <typename T>
struct FooNonPointerBase {
void valid_if_not_pointer(T) const { }
};
template <typename T>
struct Foo : public conditional<
is_pointer<T>::value,
FooPointerBase<T>,
FooNonPointerBase<T> >::type {
};
int main(int argc, char * argv[])
{
int someInt = 1020;
#if DEMONSTRATE_ERROR_CASES
Foo<int*>().valid_if_not_pointer(&someInt);
Foo<int>().valid_if_pointer(304);
#else
Foo<int*>().valid_if_pointer(&someInt);
Foo<int>().valid_if_not_pointer(304);
#endif
return 0;
}
Aber wenn das nicht kaputt ist(ist es?)Es folgt mit Sicherheit keiner guten allgemeinen Methodik zum Aktivieren und Deaktivieren von Methoden in einer Klasse mit Vorlagen, die auf dem Ermitteln des Typs für Merkmale basiert. Gibt es eine bessere Lösung?