initializer_list作为数组引用参数的参数?

时间:2014-08-25 21:03:38

标签: c++ templates c++11 reference initializer-list

以下对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;
}

1 个答案:

答案 0 :(得分:4)

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


§14.8.2.5[temp.deduct.type] / p5:

  

未推断的上下文是:

     
      
  • [...]
  •   
  • 一个函数参数,其关联参数是初始化列表(8.5.4),但参数不具有   std::initializer_list或引用可能的cv-qualified   std::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从第二个参数开始,也会产生冲突。这改变了格式良好的程序的行为,不允许进行符合扩展。)