Ich habe vor einer Woche eine Frage gestellt, in der ich gefragt wurde, wie ich eine Klassenvorlage nur dann instanziieren könnte, wenn der Typ, den sie benötigt, eine bestimmte Elementfunktion hätte. In meiner Antwort bekam ich eine Art komplizierte Lösung. Aber dann habe ich versucht, es alleine zu machen. Ich wollte nur wissen, ob dies genug, um aus einem gegebenen Typ T
hat eine void-Funktion namens f
unter 0 Parameter.Wird dies als SFINAE betrachtet?
#include <type_traits>
#include <utility>
template <typename T, typename = void>
struct has_f : std::false_type { };
template <typename T>
struct has_f<
T,
decltype(std::declval<T>().f(), void())> : std::true_type { };
template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };
struct B
{
void f();
};
struct C { };
template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’
// in ‘struct std::enable_if<false, void>’
Wenn ja, warum die anderen Antworten sind so kompliziert in this thread?
Ja verwenden, ist dies SFINAE und ja, das ist richtig. Warum sind die anderen Antworten komplizierter? Schwer zu sagen. –
Um zu verdeutlichen, dass "has_f" sich auf SFINAE stützt, tut 'A' das nicht. –
Als eine Möglichkeit, SFINAE Unterstützung in einigen Compilern (* hust * MSVC2012) Art von saugt, so könnte ein Teil dieser Komplexität Workarounds sein, um eine tragbare SFINAE haben. Nebenbei, 'std :: declval() .f()' und 'std :: declval () .f()' (oder ist es 'std :: declval () .f()'?) kann in C++ 1y aufgrund des rvalue-Verweises auf dieses Merkmal anders sein. –
Yakk