C++ 如何在模板化函数指针声明中读取如此多的星号和括号?
从 文章声称C++ 如何在模板化函数指针声明中读取如此多的星号和括号?,c++,c++11,function-pointers,declaration,C++,C++11,Function Pointers,Declaration,从 文章声称 template <class T> class tmp { public: int i; }; auto foo()->auto(*)()->tmp<int>(*)(){ return 0; } 所以foo是一个函数,它返回0,但是返回类型很复杂:它的返回类型是函数指针,它的返回类型也是函数指针,它的返回类型是tmp是一个有用的在线工具,可以解开复杂的C声明 插入int(*(*foo())())()返回: 将foo声明为函数
template <class T> class tmp {
public:
int i;
};
auto foo()->auto(*)()->tmp<int>(*)(){
return 0;
}
所以foo是一个函数,它返回0,但是返回类型很复杂:它的返回类型是函数指针,它的返回类型也是函数指针,它的返回类型是tmp
是一个有用的在线工具,可以解开复杂的C声明
插入int(*(*foo())())()
返回:
将foo声明为函数返回指向函数的指针返回指向返回int的函数的指针
我已将tmp
替换为int
,因为该工具不支持模板
一开始我应该看哪里
老实说,您应该看看,它描述了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
今天真的没有理由写这样的声明 正确格式化代码可能有助于您理解:
template <class T>
class tmp {
public:
int i;
};
auto foo() -> auto(*)() -> tmp<int>(*)() {
return 0;
}
使用函数(即func\u name()
)递归指针\u name
)可以声明返回值为指针的函数:
base_type_t (*func_name())(parameter_list);
~~~~~~~~~~~
所以现在(*func\u name())(参数列表)
可以提供另一个功能。让我们把它放回到函数指针定义语法中:
base_type_t (*(*func_name())(parameter_list))(parameter_list);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
清除参数列表(它们为空),并用正确的类型替换标识符:
base_type_t (*(*func_name())(parameter_list))(parameter_list);
tmp<int> (*(* foo ())( /* Empty */ ))( /* Empty */ );
// Turns to
tmp<int> (*(*foo())())();
base_type_t(*(*func_name())(参数列表))(参数列表);
tmp(**foo())(/*Empty*/)(/*Empty*/);
//转向
tmp(*(*foo())();
正如其他人已经建议的那样,是一个很好的代码分析器,尽管它可能会给您另一个不太容易理解的句子。在@Vittorio answer的补充中,有一些方法可以帮助我们定义复杂类型:
从未知元素开始,以螺旋/顺时针方向移动;当遇到以下元素时,用相应的英语语句替换它们:
[X]
或[]
数组X
的大小。。。或数组未定义的大小
(类型1,类型2)
传递类型1和类型2的函数返回
*
指向…的指针
继续以螺旋/顺时针方向进行此操作,直到所有代币都被覆盖。总是先解决括号中的任何问题
在这里:
您正在创建函数指针,因此必须定义函数中的所有内容,*用于指针和指针的解引用。首先,如果您正确识别代码,代码将更易于阅读;)或等的可能重复。“我不理解第二个代码示例中的复杂函数。”这正是重点;复杂函数声明不可读(除非经过专门培训才能阅读)。因此,使用另一种方法。我相当肯定,您也可以使用typedef
来实现这一点,尽管我不确定。我也相当肯定它在C++中也有作用。代码>类型定义int(*A)()代码>不是一个好的语法。真的,但是C中没有这个,我只是意识到我偶然调用C++。哦,QPayStAcess是的,这就是为什么他们把它叫做C++。这是一个更好的:-)而且明显不止一页长,如果只有ASCII艺术可以编译。。。
base_type_t (*pointer_name)(parameter_list);
base_type_t (*func_name())(parameter_list);
~~~~~~~~~~~
base_type_t (*(*func_name())(parameter_list))(parameter_list);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
base_type_t (*(*func_name())(parameter_list))(parameter_list);
tmp<int> (*(* foo ())( /* Empty */ ))( /* Empty */ );
// Turns to
tmp<int> (*(*foo())())();
+-----------+
| +------+ |
| | >-v | |
temp<int> (*(*foo())())()
| | ^---+ | |
| ^--------+ |
+--------------+
/ /
L_L_
/ \
|00 | _______
|_/ | / ___ \
| | / / \ \
| |_____\ \_ / /
\ \____/ /_____
\ _______________/______\.............................