万星星@豌豆荚 欢迎加入我们
一个吃软饭的男人!!!!!我只想写程序####
微博:http://weibo.com/wanlianwen
posts - 172,  comments - 1253,  trackbacks - 0

研究Boost前,想深入了解一下模板技术,找来一本书《C++ Template:The Complete Guide》研究。
里面有这样一个小技巧,判断一个类中是否有某种类形。下面是代码:(Win 2K+ VS2003)

#include  < iostream >

//  返回类型,大小分别为1、2
typedef  char  RT1;
typedef 
struct
{
    
char  a[ 2 ];
}
 RT2;

//  选择这个版本将返回char,大小为1
template < typename T >  RT1 test(typename T::X  const * )
{
    
int     dumy     =   0 ;
    dumy
++ ;
}


//  选择这个版本将返回char,大小为2
template < typename T >  RT2 test()
{
    
int     dumy     =   0 ;
    dumy
++ ;
}


//  依靠编译器自动选择test函数,然后依据返回类型判断是否含有X
template < typename T >
bool  type_has_member_type_X()
{
    
return  ( sizeof (test < T > ( 0 ))  ==   1 );
}


//  有X类型的类
class  HasX
{
public :
    
class  X
    
{
    }
;
}
;

//  无X类型的类
class  NonX
{
public :
    
class  Y
    
{
    }
;
}
;

int  _tmain( int  argc, _TCHAR *  argv[])
{
    
//  编译器选择重载函数策略:选择类型最匹配版本
    
//  倾向于把0转化为常量空指针,所以选择返回为RT1版本
     if (type_has_member_type_X < HasX > ())
    
{
        std::cout 
<<   " Has X "   <<  std::endl;
    }

    
else
    
{
        std::cout 
<<   " Non X "   <<  std::endl;
    }


    
//  没有T::X,所以选择返回为RT2版本
     if (type_has_member_type_X < NonX > ())
    
{
        std::cout 
<<   " Has X "   <<  std::endl;
    }

    
else
    
{
        std::cout 
<<   " Non X "   <<  std::endl;
    }

    
return   0 ;
}
输出结果:
Has X
Non X
posted on 2006-04-05 22:26 万连文 阅读(1517) 评论(3)  编辑 收藏 引用 所属分类: 模板

FeedBack:
# re: 一个模板巧妙技术,语法技巧
2006-04-06 00:23 | dicklee
有个瑕疵,X若为引用类型则会返回不期望的值,例如:
class HasX
{
public:
typedef int& X;
};
type_has_member_type_X < HasX >()
将返回false,类型和特征萃取时,引用类型总是比较麻烦,呵呵  回复  更多评论
  
# re: 一个模板巧妙技术,语法技巧
2006-04-06 13:52 | 万连文
@dicklee
不错,看来上面对模板了解深啊,现在才发现自己对编译器了解甚少!  回复  更多评论
  
# re: 一个模板巧妙技术,语法技巧
2007-08-28 09:49 | 100000
typedef char RT1;
typedef struct
{
char a[ 2 ];
} RT2;

template < typename T >
class NonRef{

public:

typedef T NonRefX;

};

template < typename T >
class NonRef< T& >{

public:

typedef T NonRefX;

};

// 选择这个版本将返回char,大小为1
template < typename T > RT1 test( typename NonRef< typename T::X >::NonRefX const * )
{
int dumy = 0 ;
dumy ++ ;
}


// 选择这个版本将返回char,大小为2
template < typename T > RT2 test(...)
{
int dumy = 0 ;
dumy ++ ;
}

// 依靠编译器自动选择test函数,然后依据返回类型判断是否含有X
template < typename T >
bool type_has_member_type_X()
{
return ( sizeof (test < T > ( 0 )) == 1 );
}

// 有X类型的类
class HasX
{
public :

typedef int& X;

} ;

// 无X类型的类
class NonX
{
public :
class Y
{
} ;
} ;


int _tmain(int argc, _TCHAR* argv[])
{
// 编译器选择重载函数策略:选择类型最匹配版本
// 倾向于把0转化为常量空指针,所以选择返回为RT1版本

if (type_has_member_type_X < HasX > ())
{
std::cout << " Has X " << std::endl;
}
else
{
std::cout << " Non X " << std::endl;
}

// 没有T::X,所以选择返回为RT2版本
if (type_has_member_type_X < NonX > ())
{
std::cout << " Has X " << std::endl;
}
else
{
std::cout << " Non X " << std::endl;
}


return 0;
}
  回复  更多评论
  

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


简历下载
联系我

<2006年11月>
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789

常用链接

留言簿(66)

随笔分类

随笔档案

相册

搜索

  •  

最新评论

阅读排行榜

评论排行榜