typedef 和 模板 可混用吗?

MyRe 2013-11-27 11:59:26
两个问题。
问题一:
假设有一个模板类
template<class T>
struct A
{
T data;
}

typedef A<T> * pA

我想定义一个新的类型pA,可是上述代码那样是错误的。正确的应该怎么定义?

问题二:
在 typedef 的百度百科上,代码用法的第5点有三个复杂的类型:

int *(*a[5])(int, char*);
void (*b[10]) (void (*)());
double(*)() (*pa)[9];

好吧,我完全看不懂
这有void的,有(int,char *)好像形参表之类的东西为什么是类型..乍一看以为是函数
请大神解释。
...全文
400 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
toofunny 2013-11-29
  • 打赏
  • 举报
回复

typedef double(* Function)();	//这里定义了一个名为Function的函数指针类型,以double为返回值类型 ,无参数
typedef Function (*FunctionArrayPointer)[9]; 
//定义一个指向一维数组的指针类型, 该数组的元素类型为Function 



int main()
{
	Function FunctionArray[1][9] ;//这里定义了Function的二维数组
	FunctionArrayPointer pArray =  FunctionArray ;
//但FunctionArrayPointer不是一维数组的指针吗?
//答:请仔细复习“行指针”知识,我几句话说不清楚。FunctionArrayPointer是个行指针。
}
还有,关于您说的越界是什么意思? 烦请解答。 答:我前面已经说了,你在内存中申请了N个字节,使用时超出了这N个字节就是越界了。 这是一方面。还有一种是你定义了一个数组,比如a[5] ;你使用了a[5]甚至a[6]也是越界了,会破坏邻接变量。 [/quote]
还有多远 2013-11-29
  • 打赏
  • 举报
回复
唉,这种复杂的语法,目前还没见过用在哪个地方过呢,下面是我的理解,抛砖引玉,仅供参考

(1)int *(*a[5])(int, char*)
写成这样应该好理解些:int* (*a[5])(int, char*)
其中左边的int*和右边的(int, char*)共同说明了一个函数类型,即参数类型为int和char*返回类型为int*的函数类型,再看中间的(*a[5]),这个表明它是元素个数为5的数组,所以连起来:
typedef int *(*a[5])(int, char*);
a array;//这里就是定义了一个数组array,这个数组中有5个元素,每一个都是一个函数指针,
        //且函数的参数类型为int和char*,返回类型为int*
(2)
void (*b[10]) (void (*)());
与(1)类似,左边的void和右边(void (*)())共同说明了一个函数类型,这种函数无返回值且参数是一个函数指针,这个函数指针指向的函数是一个无返回值且无参数的函数,中间的(*b[10])表示它是一个元素个数为10的数组,所以连起来:
typedef void (*b[10]) (void (*)());
b array;//这里就是定义了一个数组array,这个数组中有10个元素,每一个都是一个函数指针,
        //且函数无参数无返回值

注意,这里的void (*)()虽然在C++中理解成上述无参数无返回值的函数指针,但是在C中却可以是带任意参数无返回值的函数指针,且C语言标准保证函数指针解引用时参数的正确接收

(3)double(*)() (*pa)[9]
左边的double(*)()说明了一个函数类型,此函数无参数且返回值为double类型,右边的(*pa)[9]说明它是一个指针,这个指针指向一个含有9个元素的数组,所以连起来:
typedef double (*pFun)();
typedef pFun (*pa)[9];
pa p = NULL;//这里定义了一个指针,它需要指向一个数组,这个数组要含有9个元素,
            //且每个元素都是一个函数指针,函数无参数,返回值为double类型
Adol1111 2013-11-29
  • 打赏
  • 举报
回复
引用 11 楼 catonmoon 的回复:
[quote=引用 2 楼 Adol1111 的回复:] 问题一:根据C++11的说法,之前的标准不允许使用typedef给模板取别名,但有些编译器上经常看到类似的效果(应该是编译器自己实现的),新标准中用using给模板取别名。比如:
template <class T>
using My_vec = std::vector<T>;
VS2012好像还没支持这功能,gcc下未测试,有待验证。 问题二:都是函数指针而已,第一个是函数指针数组。第二个一样是函数指针数组,只是这些函数的参数也是函数指针。第三个是函数指针的二维数组。以第一个为例:
#include<iostream>
#include <vector>
using namespace std;

typedef int *(*a[5])(int, char*);

int * f(int i,char* ch){
	cout<<i<<" ff "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int * g(int i,char* ch){
	cout<<i<<" gg "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int main()
{
	a p={f,g};
	int* p1 = p[0](1,"1");
	int* p2 = p[1](2,"2");
	return 0;
}
谢谢您的回答。对此我还有些不懂: 1.

template<class T>
struct A
{
  T data;
}

template<class T>
using pA = A<T> *;

//那么实例化是这样吗?
pA<int> pInt = new A<int>;//这样VS报错
2. 关于这一句:a=(pa)malloc(sizeof(dfp)); pa是指向dfp的指针的数组吗? 如果是,那么malloc(sizeof(dfp))不是申请了一个dfp的内存空间(即4byte)吗? 那么为什么可以强制转换成pa,即9*4个dfp的空间?
int main()
{
    pa a;
    a=(pa)malloc(sizeof(dfp));
    a[0][0]=f;
    a[0][3]=g;
    a[0][0]();
    a[0][3]();
    return 0;
}
上述代码中a为什么是二维数组? typedef dfp (*pa)[9]; 这里是第二维的9,那第一维是什么时候定义的。 理解能力有限,希望能更进一步说明~谢谢[/quote] 问题一:我已经说过了,VS下对C++11更新过慢,所以不一定有这个功能,你看看VS2013有没有这个功能,没有就没办法了。目前gcc下已经除了最小垃圾回收,其他的功能都已经支持了,你可以去试一下。不过具体怎么样用我没做测试,是否这样子我也不太清楚,你可以去查查标准。 问题二,其实这里是有点问题的,我其实想表达的是指向一维的行指针,但是因为一下子找不到这个类型,所以就用其他指针代替了,因为指针的大小都是一样的。至于为什么可以转成9*4byte,你理解可能有问题了。我申请的是第一维的,但这里的9*4是第二维的,这两者无关。 我是认为typedef dfp (*pa)[9]; 已经确定了第二维是 9*4 Byte了,所以只需要申请一维空间就可以了,但后面的高手说是有问题的,属于越界。不过我也觉得只申请一维的话就直接使用二维还是有问题的,最好不要这样使用。看看下面的写法吧。
toofunny 2013-11-29
  • 打赏
  • 举报
回复
楼主啊,我觉得如果要搞明白这几个例子,你应该攻下这几个难点: ---------------------- 指向函数的指针 指针函数的定义 指针函数类型的定义 二维数组与指针的关系(互相转换、地址计算) 行指针 指向指针的指针(定义、使用、与“行指针”的区别(重点)) ---------------------- 这些东西都不是几句话能说清的,也是相对难理解的。 如果实在不行的话可以先放一放,等以后对语言有了更进一步的理解,再回头看看这些例子。这样复杂的例子在现实中很少会用到。
toofunny 2013-11-28
  • 打赏
  • 举报
回复
引用 6 楼 Adol1111 的回复:
[quote=引用 4 楼 toofunny 的回复:] [quote=引用 3 楼 Adol1111 的回复:] 第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
这个代码不错,可惜发生了越界访问。用这句代码即可看出申请到的空间只是4bytes。 cout<<sizeof(dfp)<<endl; 我冒昧修改了一下。 #include<iostream> using namespace std; typedef double(* Function)(); //函数类型 typedef Function (*FunctionArrayPointer)[9]; //指向一维数组的指针,数组元素为函数指针 double f(){ cout<<" ff "<<endl; return double(); } double g(){ cout<<" gg "<<endl; return double(); } int main() { Function FunctionArray[1][9] ; FunctionArrayPointer pArray = FunctionArray ; pArray[0][0]=f; pArray[0][1]=g; pArray[0][0]( ); pArray[0][1]( ); return 0; }[/quote] 这个是随手写的,因为malloc的时候的确有点意识到不对,不过没细想就贴上来了,实在抱歉。不过刚刚测试了下,的确没有越界。
a=(pa)malloc(sizeof(pa));
cout<<sizeof(a)<<endl;
cout<<sizeof(a[0])<<endl;
输出的是4和36,也就是说a的范围是a[0][0]-a[0][8]一共9个是没问题。a[0]的大小已经确定了。[/quote] 是你对越界的理解错误了。 你在内存中申请了N个字节,使用时超出了这N个字节就是越界了。 就算你这样写a=(pa)malloc(0); (完全没有分配内存), 或者把a=(pa)malloc(sizeof(dfp));完全去掉, cout<<sizeof(a)<<endl; cout<<sizeof(a[0])<<endl; 输出的还是4和36,因为那是从语义上的得到的,与实际内存无关。
MyRe 2013-11-28
  • 打赏
  • 举报
回复
引用 2 楼 Adol1111 的回复:
问题一:根据C++11的说法,之前的标准不允许使用typedef给模板取别名,但有些编译器上经常看到类似的效果(应该是编译器自己实现的),新标准中用using给模板取别名。比如:
template <class T>
using My_vec = std::vector<T>;
VS2012好像还没支持这功能,gcc下未测试,有待验证。 问题二:都是函数指针而已,第一个是函数指针数组。第二个一样是函数指针数组,只是这些函数的参数也是函数指针。第三个是函数指针的二维数组。以第一个为例:
#include<iostream>
#include <vector>
using namespace std;

typedef int *(*a[5])(int, char*);

int * f(int i,char* ch){
	cout<<i<<" ff "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int * g(int i,char* ch){
	cout<<i<<" gg "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int main()
{
	a p={f,g};
	int* p1 = p[0](1,"1");
	int* p2 = p[1](2,"2");
	return 0;
}
谢谢您的回答。对此我还有些不懂: 1.

template<class T>
struct A
{
  T data;
}

template<class T>
using pA = A<T> *;

//那么实例化是这样吗?
pA<int> pInt = new A<int>;//这样VS报错
2. 关于这一句:a=(pa)malloc(sizeof(dfp)); pa是指向dfp的指针的数组吗? 如果是,那么malloc(sizeof(dfp))不是申请了一个dfp的内存空间(即4byte)吗? 那么为什么可以强制转换成pa,即9*4个dfp的空间?
int main()
{
    pa a;
    a=(pa)malloc(sizeof(dfp));
    a[0][0]=f;
    a[0][3]=g;
    a[0][0]();
    a[0][3]();
    return 0;
}
上述代码中a为什么是二维数组? typedef dfp (*pa)[9]; 这里是第二维的9,那第一维是什么时候定义的。 理解能力有限,希望能更进一步说明~谢谢
MyRe 2013-11-28
  • 打赏
  • 举报
回复
引用 4 楼 toofunny 的回复:
[quote=引用 3 楼 Adol1111 的回复:] 第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
这个代码不错,可惜发生了越界访问。用这句代码即可看出申请到的空间只是4bytes。 cout<<sizeof(dfp)<<endl; 我冒昧修改了一下。 #include<iostream> using namespace std; typedef double(* Function)(); //函数类型 typedef Function (*FunctionArrayPointer)[9]; //指向一维数组的指针,数组元素为函数指针 double f(){ cout<<" ff "<<endl; return double(); } double g(){ cout<<" gg "<<endl; return double(); } int main() { Function FunctionArray[1][9] ; FunctionArrayPointer pArray = FunctionArray ; pArray[0][0]=f; pArray[0][1]=g; pArray[0][0]( ); pArray[0][1]( ); return 0; }[/quote]

typedef double(* Function)();	//这里定义了一个名为Function的函数指针类型,其以double * 
                                //为返回值且以void为参数
typedef Function (*FunctionArrayPointer)[9]; //定义了一个Function指针数组,数组容量为9,类型为                       
                                             //Function的指针?
以上理解有错误吗?

int main()
{
	Function FunctionArray[1][9] ;//这里定义了Function的二维数组
	FunctionArrayPointer pArray =  FunctionArray ;//但FunctionArrayPointer不是一维数组的指针吗?
	pArray[0][0]=f;
	pArray[0][1]=g;
	pArray[0][0](  );
	pArray[0][1](  );
	return 0;
}
还有,关于您说的越界是什么意思? 烦请解答。
ForestDB 2013-11-28
  • 打赏
  • 举报
回复
从基本的练起。
Adol1111 2013-11-28
  • 打赏
  • 举报
回复
引用 4 楼 toofunny 的回复:
[quote=引用 3 楼 Adol1111 的回复:] 第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
这个代码不错,可惜发生了越界访问。用这句代码即可看出申请到的空间只是4bytes。 cout<<sizeof(dfp)<<endl; 我冒昧修改了一下。 #include<iostream> using namespace std; typedef double(* Function)(); //函数类型 typedef Function (*FunctionArrayPointer)[9]; //指向一维数组的指针,数组元素为函数指针 double f(){ cout<<" ff "<<endl; return double(); } double g(){ cout<<" gg "<<endl; return double(); } int main() { Function FunctionArray[1][9] ; FunctionArrayPointer pArray = FunctionArray ; pArray[0][0]=f; pArray[0][1]=g; pArray[0][0]( ); pArray[0][1]( ); return 0; }[/quote] 这个是随手写的,因为malloc的时候的确有点意识到不对,不过没细想就贴上来了,实在抱歉。不过刚刚测试了下,的确没有越界。
a=(pa)malloc(sizeof(pa));
cout<<sizeof(a)<<endl;
cout<<sizeof(a[0])<<endl;
输出的是4和36,也就是说a的范围是a[0][0]-a[0][8]一共9个是没问题。a[0]的大小已经确定了。
toofunny 2013-11-28
  • 打赏
  • 举报
回复
第三个定义的不是数组,而是一个行指针
toofunny 2013-11-28
  • 打赏
  • 举报
回复
引用 3 楼 Adol1111 的回复:
第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
这个代码不错,可惜发生了越界访问。用这句代码即可看出申请到的空间只是4bytes。 cout<<sizeof(dfp)<<endl; 我冒昧修改了一下。 #include<iostream> using namespace std; typedef double(* Function)(); //函数类型 typedef Function (*FunctionArrayPointer)[9]; //指向一维数组的指针,数组元素为函数指针 double f(){ cout<<" ff "<<endl; return double(); } double g(){ cout<<" gg "<<endl; return double(); } int main() { Function FunctionArray[1][9] ; FunctionArrayPointer pArray = FunctionArray ; pArray[0][0]=f; pArray[0][1]=g; pArray[0][0]( ); pArray[0][1]( ); return 0; }
Adol1111 2013-11-28
  • 打赏
  • 举报
回复
引用 7 楼 toofunny 的回复:
[quote=引用 6 楼 Adol1111 的回复:] [quote=引用 4 楼 toofunny 的回复:] [quote=引用 3 楼 Adol1111 的回复:] 第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
这个代码不错,可惜发生了越界访问。用这句代码即可看出申请到的空间只是4bytes。 cout<<sizeof(dfp)<<endl; 我冒昧修改了一下。 #include<iostream> using namespace std; typedef double(* Function)(); //函数类型 typedef Function (*FunctionArrayPointer)[9]; //指向一维数组的指针,数组元素为函数指针 double f(){ cout<<" ff "<<endl; return double(); } double g(){ cout<<" gg "<<endl; return double(); } int main() { Function FunctionArray[1][9] ; FunctionArrayPointer pArray = FunctionArray ; pArray[0][0]=f; pArray[0][1]=g; pArray[0][0]( ); pArray[0][1]( ); return 0; }[/quote] 这个是随手写的,因为malloc的时候的确有点意识到不对,不过没细想就贴上来了,实在抱歉。不过刚刚测试了下,的确没有越界。
a=(pa)malloc(sizeof(pa));
cout<<sizeof(a)<<endl;
cout<<sizeof(a[0])<<endl;
输出的是4和36,也就是说a的范围是a[0][0]-a[0][8]一共9个是没问题。a[0]的大小已经确定了。[/quote] 是你对越界的理解错误了。 你在内存中申请了N个字节,使用时超出了这N个字节就是越界了。 就算你这样写a=(pa)malloc(0); (完全没有分配内存), 或者把a=(pa)malloc(sizeof(dfp));完全去掉, cout<<sizeof(a)<<endl; cout<<sizeof(a[0])<<endl; 输出的还是4和36,因为那是从语义上的得到的,与实际内存无关。[/quote] 好吧,我会注意的。
Adol1111 2013-11-28
  • 打赏
  • 举报
回复
第三个是数组指针,可以看下这个例子(虽然有点糟糕):
#include<iostream>
#include <vector>

typedef double(* dfp)();
typedef dfp (*pa)[9]; 

double f(){
	cout<<" ff "<<endl;
	return 1.1;
}
double g(){
	cout<<" gg "<<endl;
	return 1.1;
}


int main()
{
	pa a;
	a=(pa)malloc(sizeof(dfp));
	a[0][0]=f;
	a[0][3]=g;
	a[0][0]();
	a[0][3]();
	return 0;
}
Adol1111 2013-11-28
  • 打赏
  • 举报
回复
问题一:根据C++11的说法,之前的标准不允许使用typedef给模板取别名,但有些编译器上经常看到类似的效果(应该是编译器自己实现的),新标准中用using给模板取别名。比如:
template <class T>
using My_vec = std::vector<T>;
VS2012好像还没支持这功能,gcc下未测试,有待验证。 问题二:都是函数指针而已,第一个是函数指针数组。第二个一样是函数指针数组,只是这些函数的参数也是函数指针。第三个是函数指针的二维数组。以第一个为例:
#include<iostream>
#include <vector>
using namespace std;

typedef int *(*a[5])(int, char*);

int * f(int i,char* ch){
	cout<<i<<" ff "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int * g(int i,char* ch){
	cout<<i<<" gg "<<ch<<endl;
	int * p = (int*)malloc(sizeof(int));
	return p;
}

int main()
{
	a p={f,g};
	int* p1 = p[0](1,"1");
	int* p2 = p[1](2,"2");
	return 0;
}
worldy 2013-11-28
  • 打赏
  • 举报
回复
template<class T> struct A { T data; } typedef A<T> * pA //T应该是具体的类型比如int int *(*a[5])(int, char*); //函数指针数组,保存的函数类型为返回int*,以int*及 char为参数 void (*b[10]) (void (*)()); //指针数组。函数是以另一个函数指针做参数 double(*)() (*pa)[9]; //这个不懂

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧