С "независящим" здесь я подразумеваю "не зависящий от любых других аргументов шаблона этого шаблона конкретной функции".
Отвечая на этот вопрос, я думал, что нашел ответ, но, согласно @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 с Nov CTP, как правило, согласуется с Clang, но сбой во втором фрагменте, если функция присутствует, вероятно, потому что у них нет constexpr
. Я отправил отчет об ошибке здесь.)