Ich versuche in struct A
eine Funktion foo
(Drucke 0) zu verlassen, wenn seine Parameter Vorlage Methode isA<void>
und eine andere (Drucke 1) wenn nicht haben. Dieser Code (unten auf das minimale Beispiel reduziert) kompiliert (wird mit gcc 6.1.0 und clang-3.9.0 mit expliziter --std=c++14
Option versucht) und läuft.Warum funktioniert SFINAE in diesem Fall falsch und wie kann ich es beheben?
Aber es druckt 1, obwohl, ich bin mir sicher, dass es 0 drucken soll. Ich frage mich, wo ich falsch liege, aber echte Frage ist: Wie man diese Arbeit richtig macht?
Bitte nur C++ 14 Lösungen.
#include <type_traits>
#include <iostream>
#include <utility>
using std::enable_if;
using std::declval;
using std::true_type;
using std::false_type;
using std::cout;
template<int M>
struct ObjectX
{
template<typename C>
bool isA() { return false; }
};
struct XX : ObjectX<23456> {
int af;
};
template <typename ObjType> using has_dep = decltype(declval<ObjType>().template isA<void>());
template <typename, typename = void>
struct has_isa : public false_type {};
template <typename ObjType>
struct has_isa<ObjType, has_dep<ObjType> > : public true_type {};
template<typename ObjType>
struct A
{
template<typename T = void>
typename enable_if<has_isa<ObjType>::value, T>::type
foo() {
cout << "called foo #0" << "\n";
}
template<typename T = void>
typename enable_if<!has_isa<ObjType>::value, T>::type
foo() {
cout << "called foo #1" << "\n";
}
};
int
main()
{
A<XX> axx;
// XX().template isA<void>(); -- to check, that we can call it and it exists
axx.foo();
return 0;
}
'has_isa' wird nicht automatisch versuchen, die Spezialisierung mit' has_dep' zu instanziieren, anstatt mit 'void', falls Sie keinen zweiten Template-Parameter angeben. – Albjenow
@Albjenow dieser Ansatz funktioniert, wenn Funktionselement nicht Vorlage ist. Versuchen Sie geringfügige Änderungen am Code (entfernen Sie Template C und fix has_dep) und Sie werden sehen, dass alles andere korrekt ist. Es sollte versuchen, es zu tun, weil mehr eingeschränkte Spezialisierung immer gegen weniger eingeschränkt gewinnt –