Jinhao::天水涧
天水涧 一线之间

导航

 

难度:

文前提醒:看这篇文章时须家长陪同并引导,以免走火入魔

 

先看看下面的代码?   

struct A

{

     A(){}

};

 

template<typename T>

void func(T() )

{}

 

int main()

{

   A a( A() );    //(1), OK

   func( A() );   //(2), Wrong

   a = 5;          //(3), Wrong

}

 

(1) A  a( A() ); 是什么意思?

在这里并不是用A()创建一个对象,然后实例化对象a。这里真正的语a是一个参数为返回A对象的无参函数指针的函数,所以它的真面目应该是A a( A (*)() ) 。而这句仅仅起到声明函数的作用。重点就在于A()并不是创建对象,而是一个无参的、返回为A的无名函数

为什么说A() 是一个无名的函数呢? 来类比一下

一个普通函数应该这样写 A fun()

现在它是无名的,那么把fun去掉 就成了A()

 

(2) func( A() ); 为什么会出错呢?

这里虽然函数模板func的参数同样也是一个无参的、返回为T的函数指针,那为什么会出错呢? 其实在这里A()就不是一个无名函数了,而是创建一个临时对象。那么这个函数即成了 void func( A ),而原本的类型是void func( T (*)() ),很明显参数类型不匹配。

 

(3) a = 5; 现在应该没有任何疑问了

int 传递给 A (*)( A (*)() ),地球人都知道是错的。

 

千万别走火入魔!

是什么导致了(1)(2)中的A()表现出不同的语义呢?

答: 注意(1)是声明,当A()这个具有二意性东西出现在声明或定义中,那么它都被看作是“类型”而不是函数调用。所以这样一来,(2)明显不是定义,所以A()就被解析成调用。

 

更多

struct A

{

     A(int ){}

};

 

A a(A(1)); 在这里A(1) 就不可能是“类型”了,因为其中有个1,由于1不是“类型”,所以A(1)就成了函数调用。

//The End

posted on 2004-06-05 16:58  天水涧  阅读(1070)  评论(4)    收藏  举报