C++ 初始值设定项\u列表作为数组引用参数的参数?

C++ 初始值设定项\u列表作为数组引用参数的参数?,c++,templates,c++11,reference,initializer-list,C++,Templates,C++11,Reference,Initializer List,以下对foo的调用有效吗?GCC似乎对此很满意,而Clang为foo给出了一个“无匹配函数”错误;注意,N无法推断 template <unsigned N> void foo(const int (&x)[N]) {} int main(int argc, char *argv[]) { foo({1,2,3}); return 0; } 模板 void foo(const int(&x)[N]){ int main(int argc,char*argv[])

以下对
foo
的调用有效吗?GCC似乎对此很满意,而Clang为
foo
给出了一个“无匹配函数”错误;注意,
N
无法推断

template <unsigned N>
void foo(const int (&x)[N]) {}

int main(int argc, char *argv[])
{
  foo({1,2,3});
  return 0;
}
模板
void foo(const int(&x)[N]){
int main(int argc,char*argv[])
{
foo({1,2,3});
返回0;
}

编辑:随着2014年11月委员会会议通过的决议,OP中的代码现在被允许。编译器现在可以推断数组中元素的类型和数量


§14.8.2.5【温度扣除类型】/p5:

非推断上下文为:

  • [……]
  • 一种函数参数,其相关参数是初始值设定项列表(8.5.4),但该参数没有
    std::初始值设定项\u列表
    或对可能符合条件的cv的引用
    std::初始值设定项\u列表
    类型
  • [……]
您的初始值设定项列表是非推断上下文,因此clang正确地拒绝您的代码

可以想象,在这种情况下,g++可以作为扩展支持演绎。但是,由于该代码存在“推断冲突值”错误:

模板
结构C{};
模板
void foo(C,const int(&x)[N]){
int main(int argc,char*argv[])
{
foo(C(),{1,2,3});
返回0;
}

在我看来,它像一只虫子。(在上面代码中对
foo
的调用中,编译器应该根据标准仅从第一个参数推断
N
,因此不应该有冲突。g++也从第二个参数推断
N
,从而产生冲突。这改变了格式良好的程序的行为,这是不允许出现冲突的一致性扩展。)

它们是什么编译器版本?GCC 4.10.0(20140810)和Clang版本3.6.0(trunk 215435)。(我也在另一台机器上试用了最近的版本。)…这是否意味着GCC应该给出一个错误?是的,它不应该从初始值设定项列表中推断数组argument@40two哪一个?最初的版本还是修改后的版本?版本12.0更新2Sorry没有得到它,OP发布的版本。你发布的那个也会产生同样的错误。@402是的,好的。无论如何,MSVC对于标准一致性的推理不是很有用。
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;
}