Już kilka razy użyłem idiomu SFINAE i przyzwyczaiłem się do umieszczenia mojego std::enable_if<>
w parametrach szablonu, a nie w typach zwracanych. Jednak natrafiłem na jakiś trywialny przypadek, w którym to nie zadziałało, i nie jestem pewien dlaczego. Przede wszystkim, tutaj jest mój główny:SFINAE działa w typie zwrotnym, ale nie jako parametr szablonu
int main()
{
foo(5);
foo(3.4);
}
Oto implementacja foo
że wyzwala błąd:
template<typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
auto foo(T)
-> void
{
std::cout << "I'm an integer!\n";
}
template<typename T,
typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
auto foo(T)
-> void
{
std::cout << "I'm a floating point number!\n";
}
I tu jest podobno odpowiednik kawałek kodu, który działa dobrze:
template<typename T>
auto foo(T)
-> typename std::enable_if<std::is_integral<T>::value>::type
{
std::cout << "I'm an integrer!\n";
}
template<typename T>
auto foo(T)
-> typename std::enable_if<std::is_floating_point<T>::value>::type
{
std::cout << "I'm a floating point number!\n";
}
Moje pytanie brzmi: dlaczego pierwsza implementacja foo
wyzwala ten błąd, podczas gdy druga nie uruchamia go?
main.cpp:14:6: error: redefinition of 'template<class T, class> void foo(T)' auto foo(T) ^ main.cpp:6:6: note: 'template<class T, class> void foo(T)' previously declared here auto foo(T) ^ main.cpp: In function 'int main()': main.cpp:23:12: error: no matching function for call to 'foo(double)' foo(3.4); ^ main.cpp:6:6: note: candidate: template<class T, class> void foo(T) auto foo(T) ^ main.cpp:6:6: note: template argument deduction/substitution failed: main.cpp:5:10: error: no type named 'type' in 'struct std::enable_if<false, void>' typename = typename std::enable_if<std::is_integral<T>::value>::type> ^
EDIT:
Ok. Rzeczywista demonstracja: [1. nie udało się skompilować części] (http://ideone.com/mJ8Zp6) i [druga pomyślnie skompilowana część] (http://ideone.com/G0jBft). –
Dodatkowe informacje: to samo z VS 2012 CTP w listopadzie. –
[This] (http://flamingdangerzone.com/cxx11/2012/06/01/almost-static-if.html) powinien być dla Ciebie idealny. – Xeo