woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 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 万连文 阅读(539) 评论(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;
}
  回复  更多评论

posted on 2008-08-31 21:57 肥仔 阅读(368) 评论(0)  编辑 收藏 引用 所属分类: C++ 模板


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理