Ten kod nie skompilować w większości kompilatorów, ale najpierw ja intuicyjnie spodziewać SFINAE mnie chronić:SFINAE, odliczenie vs. instancji
typedef void (*A)();
template < typename T >
struct a_metafun { typedef typename T::type type; };
template < typename T >
typename a_metafun<T>::type f(T) {}
template < typename T>
void f(T(*)()) {}
int main() { f(A()); }
mogę rozwiązać ten problem w co najmniej dwa sposoby:
1) Zmiana definicji "metafun" (f) w celu:
template < typename T > typename T::type f(T) {}
2) określenie "a_metafun" tak, że analizuje T i ma typ jeśli T i ma jeden i nie f to nie ... ale instancję bez błędów w obu kierunkach:
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
typedef < template T, bool = has_type<T>::value >
struct a_metafun { };
typedef < template T >
struct a_metafun<T, true> { typedef typename T::type type };
Po patrząc na 14.8.2 (C++ 03) wygląda mi na to, że dokładnie określa, na jakich można zastosować warunki SFINAE. Czy jest lepsze miejsce do patrzenia? Niepowodzenie w tworzeniu już wydedukowanego szablonu, nawet podczas odliczania innego, nie wydaje się być zawarte w tym wykazie.
Innym kierunkiem, który podjąłem, aby interpretować, co sprawia, że jest to niezgodne z prawem, jest to, że odliczenie a_metafun już się odbyło i powstanie jego wnętrzności jest przyczyną błędu. SFINAE nie ma zastosowania podczas tworzenia instancji, ale tylko podczas dedukcji, czy też się mylę? Jednak w drugim przypadku, a_metafun jest poprawne i poprawnie utworzone, ale po prostu nie ma wewnątrz definicji "typu", co oznacza, że szablon próbujący utworzyć wystąpienie zawodzi z powodu zamiany.
Zasadniczo zastanawiam się, co w standardzie określa zachowanie, którego jestem świadkiem. Każdy kompilowany przeze mnie uskarżałam się, nawet na comeau. Uważam, że mają rację, nie jestem do końca pewien, dlaczego.
A więc, eksperci ... co jest? Dlaczego instancja typu, nawet w kontekście dedukcji w f(), powoduje błąd, a nie wykluczenie SFINAE?
myślę, że nie powinno się w C++ 11, a nie w C++ 03 chociaż. Zasada SFINAE (a raczej * słowa *) została nieznacznie zmieniona w C++ 11. – Nawaz