【问题标题】:Template argument deduction for array types数组类型的模板参数推导
【发布时间】:2014-02-10 19:31:02
【问题描述】:

Microsoft VC++ 2010 对此代码给出错误:

template <int D, typename T>
void Foo(T x[D]) {
  // details omitted
}

int main() {
  float x[3];
  Foo(x);  // C2784: could not deduce template argument for 'T [D]' from 'float [3]'
  return 0;
}

相同的代码通过 gcc 和 clang 的集合。

这是 VC++ 2010 的错误吗?

如果是错误:

  1. 有谁知道它是否已在更高版本的 VC++ 中得到修复?
  2. 除了显式调用Foo&lt;3, float&gt;之外,还有其他解决方法吗?

如果不是bug:

是否有 gcc 和 clang 的扩展允许它们解析模板参数?

我已将实际代码大大简化为这个小示例。我已经在其他编译器上尝试过,但我目前无法访问更新的 Microsoft 编译器。我在 SO 上发现了类似的问题,但没有一个专门针对这种情况。

【问题讨论】:

  • 使用 'Visual Studio 2013' 和 'Visual C++ Compiler Nov 2013 CTP' 我得到同样的错误。
  • 啊,对不起 gcc 和铿锵红鲱鱼。他们接受了更复杂的 Foo 版本,显然是因为他们能够从第二个参数中推断出参数。但是 MS VC++ 不接受更复杂的版本。由于复杂的版本太长无法发布,我简化为这个,但实际上并没有在 gcc 和 clang 上测试我的最后一次迭代。

标签: c++ templates visual-c++


【解决方案1】:

T x[D] 类型的参数等价于 T x[] aka T* xD 不能从中推导出来。设为void Foo(T (&amp;x)[D]) - 您以这种方式传递对数组的引用。

【讨论】:

  • 我不知道这里的模板参数推导是如何工作的,但是T x[]T *x 不是同一个类型。为什么它可以在 gcc 和 clang 中工作?
  • @bolov:是的,在参数列表中是一样的(你不能按值传递数组)。不,它在 gcc 和 clang 中不起作用,至少不适合我。
  • @BenjaminLindley 同样,我不知道这里的模板推导,所以让我们暂时忘记模板。 int x[]int *x 的类型不同。 int *x 是指针,而 int x[] 是数组类型的不完整类型。它们可以相互转换,但它们不是同一类型。现在我过去错了,但我很确定我是对的。你能解释一下我为什么错了吗?
  • @bolov 用于函数声明中的参数时它们是相同的。您甚至可以以一种方式声明一个函数,并以另一种方式定义它:void f(int* x); void f(int x[]) {...} 感谢 C 的传承。
  • @bolov:在正常的声明中,你是对的,它们不一样。但是,作为函数参数,您不能按值传递数组。因此,在我认为语言设计中的错误中,C(以及扩展的 C++)导致 看起来 像数组的参数声明实际上是一个指针。所以,作为参数,int *xint x[]相同,与int x[100]相同,与int x[9999999]相同。同样,这用于参数。您指出数组不是指针是对的,请继续这样做。
猜你喜欢
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2011-10-07
相关资源
最近更新 更多