这里的“不依赖”是指“不依赖于该特定函数模板的任何其他模板参数”。
回答的同时这个问题 https://stackoverflow.com/q/15232758/500104,我以为我找到了答案,但根据@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);
}
(现场版。 http://liveworkspace.org/code/2hMZJv)
是否能保证上述内容能够编译?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);
}
(现场版。 http://liveworkspace.org/code/45Q6eT)
第二个片段只会打印foo(int)
if T
包含一个constexpr
静态函数f
。有趣的是,如果你完全删除f
from Y
(或者通过,比如说,int
相反),GCC 抱怨缺少一个成员,表明它不允许 SFINAE - 这与之前的观察相矛盾。 Clang 接受所有变体并应用 SFINAE,我想知道这是否是标准所保证的。
(FWIW,具有 Nov CTP 的 MSVC 通常与 Clang 一致,但如果该函数存在,则在第二个片段上崩溃,可能是因为它们没有constexpr
。我提交了错误报告here https://connect.microsoft.com/VisualStudio/feedback/details/780779/.)