Допускают ли независимые аргументы шаблона по умолчанию шаблонов функций SFINAE?
Под «независимым» здесь я подразумеваю «независимый от любых других аргументов шаблона этого конкретного шаблона функции».
Отвечаяэтот вопросЯ думал, что нашел ответ, но, согласно @Johannes (в комментариях к моему ответу), я неправильно интерпретирую стандарт здесь. Возьмите следующий простой пример:
#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);
}
Есть ли гарантия, что вышеперечисленные компилируются? GCC и Clang здесь не согласны, что можно увидеть в живой версии при переключении между ними. Интересно, что GCC принимает следующее:
#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);
}
Второй фрагмент будет только печататьfoo(int)
еслиT
содержитconstexpr
статическая функцияf
, Опять интересно, если полностью убратьf
изY
(или передать, скажем,int
вместо этого) GCC жалуется на пропавшего участника, указывая, что он не допускает SFINAE, что противоречит предыдущему наблюдению. Clang принимает все варианты и применяет SFINAE, и мне интересно, гарантировано ли это стандартом.
(FWIW, MSVC с ноябрьским CTP обычно соглашается с Clang, но вылетает во втором фрагменте, если функция присутствует, вероятно, потому что у них нетconstexpr
, Я отправил отчет об ошибкеВот.)