Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在模板化函数指针声明中读取如此多的星号和括号?_C++_C++11_Function Pointers_Declaration - Fatal编程技术网

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  |       _______
|_/  |      /  ___  \
|    |     /  /   \  \
|    |_____\  \_  /  /
 \          \____/  /_____
  \ _______________/______\.............................