C++类型推断递归函数
问题描述:
试图理解为什么类型推导在这里与条件运算符一起失败。
在这种情况下,标准中的某些东西试图防止类型扣除?任何理解这一点的指针都会很棒。C++类型推断递归函数
auto mfact(int i)
{
return (0==i) ? 1 : i * mfact(i-1);
}
auto mfact2(int i)
{
if (0 == i)
return 1;
else
return i * mfact2(i-1);
}
error: use of ‘auto mfact(int)’ before deduction of ‘auto’ return (0==i) ? 1 : i * mfact(i-1);
答
在mfact
问题是三元运算符。该运算符的语义指定表达式的类型是两个条件子表达式的常见类型(我正在解释一下)。
什么是常见类型?为什么它是int
和...一个类型需要推导出来。
啊,没问题!什么类型可以被推断?这是三元操作符的类型...
我们有鸡和鸡蛋的问题。整个函数定义不合格,因为表达式的类型不能确定。
mfact2
怎么样?它有两个单独的返回语句。第一个是纯整数。由于一个函数只能有一个返回类型,所以返回类型推导要求两个返回返回语句不会发生冲突。
引述C++ 14标准的修订:
占位符类型可以在 DECL说明符-SEQ,类型说明符-SEQ,变换的函数声明出现功能id或 尾随返回类型,在任何情况下,这样的声明是有效的。 如果函数声明符包含尾随返回类型 ([dcl.fct]),它指定函数的声明返回类型。 如果函数的声明返回类型包含占位符 类型,则函数的返回类型从函数正文中的返回 语句推导出,如果有,则返回。
所以一个return语句推断类型是不够的,:
如果与含有一个占位符 类型声明的返回类型的函数有多个return语句,返回类型推导为 每个返回语句。如果推导的类型在每个 扣除中不相同,则该程序是不合格的。
在这个简单的情况下,第一条语句要求它int
,而第二个包含一个递归调用。由于相同的函数重载只能有一个返回类型,所以递归调用也必须是int
。两份退货声明同意。
您应该*至少*发布您的编译器错误消息。在*最佳*后发布[mcve]。 –
一旦函数中的所有代码都被检查过,就会推导出返回类型。因此在函数的代码中使用函数签名是不成熟的。你必须在声明中声明返回类型。 –
@RichardHodges如果您交换条件,将'return i * mfact2(i-1)'放在'return 1;'之上,'mfact2'无法编译。这是否意味着该类型是由编译器发现的第一个return语句推导出来的?使用GCC 7.1.1 – 2017-07-30 17:43:37