这里的“不依赖”是指“不依赖于该特定函数模板的任何其他模板参数”。
在回答这个问题时,我以为我找到了答案,但根据@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,带有 Nov CTP 的 MSVC 通常同意 Clang,但如果该功能存在,则在第二个片段上崩溃,可能是因为他们没有。我在这里constexpr
提交了错误报告。)