Czy nie zależne domyślne argumenty szablonów szablonów funkcji pozwalają na SFINAE?
Mam tu na myśli „nie zależny” „nie zależny od innych argumentów szablonu tego konkretnego szablonu funkcji”.
Podczas odpowiadaniato pytanie, Myślałem, że znalazłem odpowiedź, ale według @Johannesa (w komentarzach do mojej odpowiedzi) błędnie interpretuję ten standard. Weźmy następujący prosty przykład:
#include <type_traits>
template<class T>
struct X{
template<class U = typename T::type>
static void foo(int){}
static void foo(...){}
};
int main(){
X<std::enable_if<false>>::foo(0);
}
Czy istnieje jakaś gwarancja, że powyższe zestawia? GCC i Clang nie zgadzają się tutaj, co widać w wersji live podczas przełączania między nimi. Co ciekawe, GCC akceptuje następujące kwestie:
#include <type_traits>
template<class T>
struct X{
template<bool = T::f()>
static void foo(int){}
static void foo(...){}
};
struct Y{
static bool f(){ return true; }
};
int main(){
X<Y>::foo(0);
}
Drugi fragment będzie drukowany tylkofoo(int)
JeśliT
zawiera aconstexpr
funkcja statycznaf
. Znowu, co ciekawe, jeśli całkowicie usunieszf
zY
(lub przejść, powiedzmy,int
zamiast tego), GCC skarży się na brakujący element, wskazując, że nie pozwala na SFINAE - co jest sprzeczne z poprzednią obserwacją. Clang bierze wszystkie wariacje i stosuje SFINAE, i zastanawiam się, czy to jest gwarantowane przez standard.
(FWIW, MSVC z Nov CTP generalnie zgadza się z Clangiem, ale zawiesza się na drugim fragmencie, jeśli funkcja jest obecna, prawdopodobnie dlatego, że nie maconstexpr
. Wysłałem raport o błędzietutaj.)