我很惊讶地发现GCC允许函数在使用尾随返回类型而不是正常返回类型时返回数组。你可能知道数组不能被复制,所以这是非常有限的但是让我给你看一些很酷的example。
#include <iostream>
#include <typeinfo>
using namespace std;
auto func() -> int [5]
{
return {4, 56, 78, 4, 0};
}
int main()
{
cout << func()[2] << endl;
cout << typeid(func).name() << endl;
}
这是编译器错误还是一些新功能?
有趣的是&#39; typeid&#39;返回&#39; FA5_ivE&#39;被解构为&#39; int (()) [5]
&#39;这意味着你认为函数返回5个int的数组。
编辑:我尝试将返回的数组绑定到右值引用但没有任何成功(使用大多数可能的形式):
auto &&refArrayTemp{ func() };
似乎这种扩展毫无用处。
答案 0 :(得分:13)
这是一个bug in gcc(固定as of 2017-07-03),由跟踪返回类型的不一致处理引起。
首先注意两次尝试声明返回函数的函数之间的错误消息的区别:
using Fv = void();
Fv f1(); // error: 'f1' declared as function returning a function
auto f2() -> Fv; // error: function return type cannot be function
第一个错误来自decl.c
,处理声明符,而第二个错误来自tree.c
,更深入到内部,尝试构建准备生成代码的函数类型。
尾随返回类型在decl.c 30 lines below中处理上述错误 - 用上面的错误代码捕获它太晚了,并且没有单独处理。
对于数组,类似地使用trailing-return-type允许我们跳过decl.c
中的检查,区别在于function-returning-array实际上在gcc的内部表示方面是有效的。
请注意,你不能做太多事情; gcc不允许您分配,引用绑定,衰减或将func()
的结果传递给另一个函数:
auto a1 = func();
// error: invalid use of non-lvalue array
auto& a2 = func();
// error: invalid initialization of non-const reference of type 'int (&)[5]' from an rvalue of type 'int [5]'
auto&& a3 = func();
// error: lvalue required as unary '&' operand
的确,即使您的代码在-Wpedantic
warning: ISO C++ forbids subscripting non-lvalue array
最后,通过利用类似的bug(在处理trailing-return-types之前从标量中删除限定符),我们可以创建一个类型为int const volatile()
的函数:
int const volatile g1(); // warning: type qualifiers ignored on function return type
auto g2() -> int const volatile; // OK!!
答案 1 :(得分:8)
最新草案,[dcl.array] / p10:
函数不应具有类型数组或函数的返回类型,尽管它们的返回类型可能为 类型指针或对此类事物的引用。虽然可以有数组,但不应有任何函数数组 指向函数的指针。
这可能是非标准的GCC扩展。 It doesn't compile in the trunk version of clang.但是,这可能也是一个错误,因为它与non-trailing return type的行为不一致。