Kompilacja musi zakończyć się niepowodzeniem w każdym zgodnym kompilatorze.
Reguły SFINAE są oparte na deklaracjach, a nie definicjach. (. Przepraszam, jeśli używam niewłaściwego terminologii tutaj) Chodzi mi o to:
dla klasy/struct:
template < /* substitution failures here are not errors */ >
struct my_struct {
// Substitution failures here are errors.
};
dla funkcji:
template </* substitution failures here are not errors */>
/* substitution failures here are not errors */
my_function(/* substitution failures here are not errors */) {
/* substitution failures here are errors */
}
Ponadto , brak istnienia struktury/funkcji dla danego zestawu argumentów szablonu podlega również zasadom SFINAE.
Teraz static_assert
może pojawić się tylko w regionach, w których awarie podstawiania są błędami, a zatem jeśli zostanie uruchomiony, otrzymasz błąd kompilatora.
Na przykład następujący byłoby źle realizacja enable_if
:
// Primary template (OK)
template <bool, typename T>
struct enable_if;
// Specialization for true (also OK)
template <typename T>
struct enable_if<true, T> {
using type = T;
};
// Specialization for false (Wrong!)
template <typename T>
struct enable_if<false, T> {
static_assert(std::is_same<T, T*>::value, "No SFINAE here");
// The condition is always false.
// Notice also that the condition depends on T but it doesn't make any difference.
};
Następnie spróbuj tego
template <typename T>
typename enable_if<std::is_integral<T>::value, int>::type
test(const T &t);
void test(...);
int main()
{
std::cout << std::is_same<decltype(test(0)), int>::value << std::endl; // OK
std::cout << std::is_same<decltype(test(0.0)), void>::value << std::endl; // Error: No SFINAE Here
}
Jeśli usuniesz specjalizację enable_if
dla false
następnie kod kompiluje i wyjścia
1
1
możliwy duplikat [Jak zmusić klienta do wywoływania wyraźnie wyspecjalizowanego szablonu zamiast podstawowego szablonu?] (http://stackoverflow.com/questions/16286303/how-can-can-i-force--client-to-call- an-explicit-specjalistyczne-szablon-zamiast-t) –