【问题标题】:Why type-deduction for arrays prioritizes pointer to first over reference to array?为什么数组的类型推断优先于指向数组的指针而不是数组的引用?
【发布时间】:2014-01-25 18:40:29
【问题描述】:
int v[1];
auto  p1 = v;
auto &p2 = v;
auto *p3 = v;

p1int * 类型(p3 相同)。特别是在这个微不足道的示例中,我发现 p2 ( int (&)[1] ) 更有用,因为它具有数组语义,例如我可以在p2 上申请sizeof 以与v 上的sizeof 相同。

对此有标准报价吗?

为什么默认引用是一个坏主意? (对于这种数组情况,我的意思是,这些天几乎没有 c++ 程序员关心它们......)

【问题讨论】:

  • Is there a standard quotation regarding that? 7.1.6.4/7 指定使用auto 进行类型推导的规则与模板参数推导的规则相同(模initializer_list)。然后,14.8.2.1/2(用于模板参数推导)指定从数组类型到指针类型的衰减只发生在非引用参数。
  • 可能还需要注意这同样适用于函数类型。如果把v的定义改成void v(),那么p1就是void(*)()p2就是void(&)()
  • C 没有引用,因此数组在作为函数参数传递时会衰减为指针。 C++ 继承了 C 的行为以实现兼容性。
  • @Praetorian 是的,最后,我想我是在讨论天使的性别...
  • 您忘记了auto &&p4 = v;,即int (&)[1]p2

标签: c++ templates c++11 auto type-deduction


【解决方案1】:

auto 推导出非引用类型。

auto& 推导出一个引用。

auto const& 推导出 const 引用。

auto&& 推导出引用、const 引用或右值引用。

这就像调用template 函数时的类型推导一样。

template<typename T>
void foo( T t );

T永远不会被推导出为引用类型——推导时它始终是值类型。

auto 遵循几乎相同的规则:

template<typename T>
void foo( T&& t );

是众所周知的“通用引用”,类似于auto&amp;&amp; 类型的变量。

【讨论】:

  • 权威答案值得引用 ;-) 无论如何,Andy Prowl 评论得很好,遗憾的是这不是一个答案。标准是这样说的,但我还是想知道历史原因和/或强烈的论据,说明它不可能不带来太多麻烦。
【解决方案2】:

我相信这是为了与非模板函数保持一致。数组在被访问的任何时候都会经历数组到指针的转换,除非绑定到引用。所以与现有的规则,以下是一致的:

int v[1];

void foo(int *);

int main()
{
  foo(v);
}

int v[1];

template <class T>
void foo(T);

int main()
{
  foo(v);
}

【讨论】:

  • 模板代码中的类型推导有点类似于auto。我的意思是我可以使用纯 c++98 =) 中的模板来做同样的问题。但无论如何,我可以预见模板参数解析为数组引用,就像它可能用于自动一样,仍然存在疑问,这是最糟糕的地方吗?我知道关于数组衰减到指针的规则,但我没有看到它排除了对指针类型引用的绑定。我明白了,虽然衰减到指针规则是一致的......
  • @pepper_chico 模板化代码的类型推导与auto 几乎完全相同(实际上反过来);这就是我在答案中使用模板的原因。另请注意,这将是不包括词法 &amp;&amp;&amp; 的参数可以推断为引用的唯一情况 - 我会说这是一个非常丑陋的例外。
猜你喜欢
  • 2018-01-06
  • 1970-01-01
  • 2012-12-12
  • 2012-05-12
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-02-07
  • 2012-02-18
相关资源
最近更新 更多