Jia*_*ang 11 c++ function-pointers declaration c++11
文章声称
template <class T> class tmp {
public:
int i;
};
auto foo()->auto(*)()->tmp<int>(*)(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
相当于
template <class T> class tmp{
public:
int i;
};
tmp<int> (*(*foo())())() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我不理解第二个代码示例中的复杂函数.我应该在一开始看哪里?我想是的foo.但旁边的统计数据foo将定义foo为指针......基于第一个代码示例,我将把这个片段转换为
tmp<int> (*)() (*)() foo(){ return 0;}
Run Code Online (Sandbox Code Playgroud)
所以foo是一个函数,返回0,但返回类型很棘手:它的返回类型是函数指针,其返回类型又是返回类型为的函数指针tmp<int>.
Bar*_*rry 24
我应该在一开始看哪里?
老实说,你应该看一下https://cdecl.org/,它描述int (*(*foo())())();为:
声明foo为函数返回指向函数的指针返回指向返回int的函数的指针
然后意识到这是C++ 11,我们有一个很好的语法来声明函数指针别名:
using A = int(*)(); // pointer to function returning int
using B = A(*)(); // pointer to function returning pointer to function returning int
B foo(); // function returning pointer to function returning pointer to function returning int
Run Code Online (Sandbox Code Playgroud)
今天真的没有理由写这样的声明.
YSC*_*YSC 17
与@Vittorio答案相辅相成,有顺时针螺旋规则来帮助我们decypher复杂类型:
从未知元素开始,以螺旋/顺时针方向移动; 当遇到以下元素时,用相应的英语语句替换它们:
[X] 要么 []
数组
X大小...或数组未定义大小...
(type1, type2)
函数传递type1和type2返回...
*
指针...
继续以螺旋/顺时针方向执行此操作,直到所有令牌都被覆盖.始终先解决括号中的任何内容!
这里:
+-----------+
| +------+ |
| | >-v | |
temp<int> (*(*foo())())()
| | ^---+ | |
| ^--------+ |
+--------------+
Run Code Online (Sandbox Code Playgroud)
foo是一个返回指向函数的指针的函数,该函数返回指向返回a的函数的指针temp<int>.
而现在,@ UKmonkey刚刚将此规则重命名为C++ Guru Snail Rule或简称CGSR:
/ /
L_L_
/ \
|00 | _______
|_/ | / ___ \
| | / / \ \
| |_____\ \_ / /
\ \____/ /_____
\ _______________/______\.............................
Run Code Online (Sandbox Code Playgroud)
正确格式化代码可能有助于您理解:
template <class T>
class tmp {
public:
int i;
};
auto foo() -> auto(*)() -> tmp<int>(*)() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
template <class T>
class tmp{
public:
int i;
};
tmp<int> (*
( *foo() )()
)() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
该template class部分仍然是相同的,所以我不打算细说了.我们来看看这个功能吧foo.
在第一个代码中,foo()is 的返回值是auto(*)() -> tmp<int>(*)()指向返回另一个指针的函数的指针,该指针指向返回的函数tmp<int>.
因为你总是可以定义一个函数指针,如:
base_type_t (*pointer_name)(parameter_list);
Run Code Online (Sandbox Code Playgroud)
pointer_name使用函数(即func_name())递归可以声明一个返回值为指针的函数:
base_type_t (*func_name())(parameter_list);
~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
所以现在(*func_name())(parameter_list)可以提供另一种功能.让我们把它放回到函数指针定义语法中:
base_type_t (*(*func_name())(parameter_list))(parameter_list);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
清除参数列表(它们是空的)并用正确的类型替换标识符给出:
base_type_t (*(*func_name())(parameter_list))(parameter_list);
tmp<int> (*(* foo ())( /* Empty */ ))( /* Empty */ );
// Turns to
tmp<int> (*(*foo())())();
Run Code Online (Sandbox Code Playgroud)
正如其他人已经建议的那样,https://cdecl.org/是一个很好的代码分析器,虽然它可能会给你另一个不太容易理解的句子.