In MSVC2017 das funktioniert gut, beide static_asserts nicht wie erwartet ausgelöst:Warum funktioniert dieses SFINAE-Snippet nicht in g ++, funktioniert aber in MSVC?
template <typename T>
struct do_have_size {
template <typename = decltype(std::declval<T>().size())>
static std::true_type check(T);
static std::false_type check(...);
using type = decltype(check(std::declval<T>()));
};
int main() {
using TR = typename do_have_size<std::vector<int>>::type;
using FL = typename do_have_size<int>::type;
static_assert(std::is_same<TR, std::true_type>::value, "TRUE");
static_assert(std::is_same<FL, std::false_type>::value, "FALSE");
}
Wenn ich jedoch in g ++ 7.1 oder Klirren 4.0 Ich erhalte folgende Compiler-Fehler kompilieren:
In instantiation of 'struct do_have_size<int>':
20:39: required from here
9:24: error: request for member 'size' in 'declval<do_have_size<int>::TP>()', which is of non-class type 'int'
Aus mein Verständnis von SFINAE, Ersatz der true_type
Rückgabe-Funktion sollte für int
Parameter fehlschlagen und nächste Funktion gewählt werden, wie es in MSVC getan wird. Warum erstellen clang und g ++ überhaupt nichts?
Ich habe mit -std=c++17
nur Switch kompiliert, vielleicht ist mehr nötig?
Wenn Sie C++ 17 verwenden, fragen Sie nach C++ 11. – Yakk
Ich kann nicht sicher herausfinden, ob 'is_detected' es in C++ 17 geschafft hat. Wenn dem so ist, scheint das perfekt dafür zu sein. Und selbst wenn nicht, sollte die Implementierung von 'std :: experimental :: is_detected' bei cppreference.com es einfach machen. –