以下对foo
的通话是否有效?海湾合作委员会似乎对它很满意,而克朗则给出了一个没有匹配功能的#34; foo
的错误;以及N
无法推断的说明。
template <unsigned N>
void foo(const int (&x)[N]) {}
int main(int argc, char *argv[])
{
foo({1,2,3});
return 0;
}
答案 0 :(得分:4)
编辑:在委员会2014年11月的会议上通过了CWG issue 1591的决议,现在允许OP中的代码。编译器现在可以推断出数组中元素的类型和数量。
§14.8.2.5[temp.deduct.type] / p5:
未推断的上下文是:
- [...]
- 一个函数参数,其关联参数是初始化列表(8.5.4),但参数不具有
std::initializer_list
或引用可能的cv-qualifiedstd::initializer_list
类型。- [...]
您的初始化列表是一个非推断的上下文,因此clang正确拒绝您的代码。
可以想象,g ++可以在这种情况下支持演绎作为扩展。但是,因为rejects此代码带有“推断出的冲突值”错误:
template<unsigned N>
struct C { };
template <unsigned N>
void foo(C<N>, const int (&x)[N]) {}
int main(int argc, char *argv[])
{
foo(C<4>(), {1,2,3});
return 0;
}
对我来说这看起来像个错误。 (在上面代码中对 foo
的调用中,编译器应该仅根据标准从第一个参数推导出N
,因此不存在冲突.g ++推导N
从第二个参数开始,也会产生冲突。这改变了格式良好的程序的行为,不允许进行符合扩展。)