请考虑以下代码:
template<typename T>
char (&f(T[1]))[1];
template<typename T>
char (&f(...))[2];
int main() { char c[sizeof(f<void()>(0)) == 2]; }
我预计它会做 SFINAE 并选择第二个重载,因为替换T
为T[1]
产量
void [1]()
当然,这是无效的类型。在将模板参数替换为函数参数并检查有效的结果类型(如 14.8.2 [temp.deduct] 描述)之后,完成参数类型(数组->指针)的调整。
但是 comeau 和 GCC 都无法编译上述内容。两者都有不同的诊断。
科莫 说:
“ComeauTest.c”,第 2 行:错误:不允许使用函数数组
char (&f(T[1]))[1];
GCC 说(版本4.3.3
):
错误:ISO C++ 禁止零大小数组
c
意思是,GCC 没有替换失败,但是它选择了 的第一个重载f
,返回sizeof
1 的 a,而不是像 Comeau 那样没有替换它。
什么编译器是正确的,我的代码是否有效?请在您的答案中参考或引用适当的标准部分。谢谢!
更新:标准本身在列表中包含这样一个示例14.8.2/2
。我不知道,为什么我首先忽略了它:
template <class T> int f(T[5]);
int I = f<int>(0);
int j = f<void>(0); // invalid array
虽然这个例子只是提供信息,但它显示了所有这些神秘段落的意图,并且似乎表明上面的代码应该可以工作并拒绝第一个重载。