原文地址:
http://www.smth.edu.cn/bbsanc.php?path=%2Fgroups%2Fdevelop.faq%2FProgramming%2Flanguages%2Fc_cpp%2Fboost%2FM.1021441404.O0
发信人:flier(小海(:好日子不多了:)),信区:Programming
标题:boost::static_assert
发信站:BBS水木清华站(WedMay1513:43:352002)
BOOST_STATIC_ASSERT是一个简单但常用的宏,顾名思义起到编译期
断言的功效,可以通过它,在编译时对开发环境以及类型定义进行检查。
此类型检测对程序运行时无任何效率和空间上的影响。
例如在namespace中加入
namespacemy_conditions{
BOOST_STATIC_ASSERT(sizeof(int)*CHAR_BIT>=32);
BOOST_STATIC_ASSERT(WCHAR_MIN>=0);
}//namespacemy_conditions
确保int类型至少32位,wchar_t类型为unsigned。
也可以在模板函数中检测入口参数的类型是否符合要求
template<classRandomAccessIterator>
RandomAccessIteratorfoo(RandomAccessIteratorfrom,RandomAccessIteratorto)
{
//thistemplatecanonlybeusedwith
//randomaccessiterators...
typedeftypenamestd::iterator_traits
<RandomAccessIterator>::iterator_categorycat;
BOOST_STATIC_ASSERT((boost::is_convertible
<cat,conststd::random_access_iterator_tag&>::value));
//
//detailgoeshere...
returnfrom;
}
确保foo函数的输入迭代子符合randomaccessiterator的concept
此外还可以在模板类里面验证模板参数
template<classUnsignedInt>
classmyclass
{
private:
BOOST_STATIC_ASSERT(sizeof(UnsignedInt)*CHAR_BIT>=16);
BOOST_STATIC_ASSERT(std::numeric_limits<UnsignedInt>::is_specialized
&&std::numeric_limits<UnsignedInt>::is_integer
&&!std::numeric_limits<UnsignedInt>::is_signed);
public:
/*detailshere*/
};
通过以上示例,我们可以总结出BOOST_STATIC_ASSERT的基本使用规律
首先是全局上对编译环境进行检测,看是否符合设计开发时的假定,这对程序的
可移植性有很大帮助。其次是在模板类、模板函数中,对作为模板参数的类型
进行检测,验证其是否符合设计时假设。最后是能够将gp中的concept概念贯彻
到代码中,使代码强制性与设计同步,并增强代码可读性。
在实现上,BOOST_STATIC_ASSERT宏利用c++规范中,对不完整类型
即不可实例化的类型,在对其进行sizeof运算时编译错误的特性,完成功能
大概的简化代码如下
template<boolx>structSTATIC_ASSERTION_FAILURE;
template<>structSTATIC_ASSERTION_FAILURE<true>{};
template<intx>structstatic_assert_test{};
#defineBOOST_STATIC_ASSERT(B)/
typedefstatic_assert_test<sizeof(STATIC_ASSERTION_FAILURE<B>>/
boost_static_assert_typedef_##__LINE__
注意为了能够使用多个BOOST_STATIC_ASSERT,在类型命名时加入了
行号以区别。对namespace而言,因为同一namespace可能分布在多个不同的
头文件中,而不同头文件中可能在同一行使用BOOST_STATIC_ASSERT检测,
所以必须用一个namespace把断言检测隔离开,如上面例子所示。
此外,对于VC来说,在使用/ZI参数时,__LINE__宏会发生错误,
(参见MSDN中Q199057错误),好在VC会忽略typedef重复定义。
对某些不支持typedef此类特性的编译器,boost提供了使用enum的替代方案
//(C)CopyrightJohnMaddock2000.
//Permissiontocopy,use,modify,selland
//distributethissoftwareisgrantedprovidedthiscopyrightnoticeappears
//inallcopies.Thissoftwareisprovided"asis"withoutexpressorimplied
//warranty,andwithnoclaimastoitssuitabilityforanypurpose.
//Seehttp://www.boost.orgformostrecentversionincludingdocumentation.
/*
Revisionhistory:
02August2000
Initialversion.
*/
#ifndefBOOST_STATIC_ASSERT_HPP
#defineBOOST_STATIC_ASSERT_HPP
#include<boost/config.hpp>
#ifdef__BORLANDC__
//
//workaroundforbuggyintegral-constantexpressionsupport:
#defineBOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS
#endif
namespaceboost{
//HPaCCcannotdealwithmissingnamesfortemplatevalueparameters
template<boolx>structSTATIC_ASSERTION_FAILURE;
template<>structSTATIC_ASSERTION_FAILURE<true>{};
//HPaCCcannotdealwithmissingnamesfortemplatevalueparameters
template<intx>structstatic_assert_test{};
}
//
//Implicitinstantiationrequiresthatallmemberdeclarationsbe
//instantiated,butthatthedefinitionsare*not*instantiated.
//
//It'snotparticularlyclearhowthisappliestoenum'sortypedefs;
//botharedescribedasdeclarations[7.1.3]and[7.2]inthestandard,
//howeversomecompilersuse"delayedevaluation"ofoneormoreof
//thesewhenimplicitlyinstantiatingtemplates.Weusetypedefdeclarations
//bydefault,buttrydefiningBOOST_USE_ENUM_STATIC_ASSERTiftheenum
//versiongetsbetterresultsfromyourcompiler...
//
//Implementation:
//Bothoftheseversionsrelyonsizeof(incomplete_type)generatinganerror
//messagecontainingthenameoftheincompletetype.Weuse
//"STATIC_ASSERTION_FAILURE"asthetypenameheretogenerate
//aneyecatchingerrormessage.Theresultofthesizeofexpressioniseither
//usedasanenuminitialiser,orasatemplateargumentdependingwhichversion
//isinuse...
//Notethattheargumenttotheassertisexplicitlycasttoboolusingold-
//stylecasts:toomanycompilerscurrentlyhaveproblemswithstatic_cast
//whenusedinsideintegralconstantexpressions.
//
#if!defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS)&&!defined(__MWERKS__)
#ifndefBOOST_MSVC
#defineBOOST_STATIC_ASSERT(B)/
typedef::boost::static_assert_test</
sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)>/
BOOST_JOIN(boost_static_assert_typedef_,__LINE__)
#else
//__LINE__macrobrokenwhen-ZIisusedseeQ199057
//fortunatelyMSVCignoresduplicatetypedef's.
#defineBOOST_STATIC_ASSERT(B)/
typedef::boost::static_assert_test</
sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)/
>boost_static_assert_typedef_
#endif
#else
//alternativeenumbasedimplementation:
#defineBOOST_STATIC_ASSERT(B)/
enum{BOOST_JOIN(boost_static_assert_enum_,__LINE__)/
=sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)}
#endif
#endif//BOOST_STATIC_ASSERT_HPP
--
.生命的意义在于//____///_///_/.
.希望///___/_//////_/______★.
.工作//____////////'__`///`'_/.
.爱你的人///___////___/////__//////.
.和你爱的人//___///_____//__//____///_/.
.……//___///_____///__///____///_/@126.com.
※来源:·BBS水木清华站bbs.edu.cn·[FROM:202.114.32.225]
http://www.smth.edu.cn/bbsanc.php?path=%2Fgroups%2Fdevelop.faq%2FProgramming%2Flanguages%2Fc_cpp%2Fboost%2FM.1021441404.O0
发信人:flier(小海(:好日子不多了:)),信区:Programming
标题:boost::static_assert
发信站:BBS水木清华站(WedMay1513:43:352002)
boost::static_assert
BOOST_STATIC_ASSERT的使用
BOOST_STATIC_ASSERT是一个简单但常用的宏,顾名思义起到编译期
断言的功效,可以通过它,在编译时对开发环境以及类型定义进行检查。
此类型检测对程序运行时无任何效率和空间上的影响。
例如在namespace中加入
namespacemy_conditions{
BOOST_STATIC_ASSERT(sizeof(int)*CHAR_BIT>=32);
BOOST_STATIC_ASSERT(WCHAR_MIN>=0);
}//namespacemy_conditions
确保int类型至少32位,wchar_t类型为unsigned。
也可以在模板函数中检测入口参数的类型是否符合要求
template<classRandomAccessIterator>
RandomAccessIteratorfoo(RandomAccessIteratorfrom,RandomAccessIteratorto)
{
//thistemplatecanonlybeusedwith
//randomaccessiterators...
typedeftypenamestd::iterator_traits
<RandomAccessIterator>::iterator_categorycat;
BOOST_STATIC_ASSERT((boost::is_convertible
<cat,conststd::random_access_iterator_tag&>::value));
//
//detailgoeshere...
returnfrom;
}
确保foo函数的输入迭代子符合randomaccessiterator的concept
此外还可以在模板类里面验证模板参数
template<classUnsignedInt>
classmyclass
{
private:
BOOST_STATIC_ASSERT(sizeof(UnsignedInt)*CHAR_BIT>=16);
BOOST_STATIC_ASSERT(std::numeric_limits<UnsignedInt>::is_specialized
&&std::numeric_limits<UnsignedInt>::is_integer
&&!std::numeric_limits<UnsignedInt>::is_signed);
public:
/*detailshere*/
};
通过以上示例,我们可以总结出BOOST_STATIC_ASSERT的基本使用规律
首先是全局上对编译环境进行检测,看是否符合设计开发时的假定,这对程序的
可移植性有很大帮助。其次是在模板类、模板函数中,对作为模板参数的类型
进行检测,验证其是否符合设计时假设。最后是能够将gp中的concept概念贯彻
到代码中,使代码强制性与设计同步,并增强代码可读性。
BOOST_STATIC_ASSERT的实现
在实现上,BOOST_STATIC_ASSERT宏利用c++规范中,对不完整类型
即不可实例化的类型,在对其进行sizeof运算时编译错误的特性,完成功能
大概的简化代码如下
template<boolx>structSTATIC_ASSERTION_FAILURE;
template<>structSTATIC_ASSERTION_FAILURE<true>{};
template<intx>structstatic_assert_test{};
#defineBOOST_STATIC_ASSERT(B)/
typedefstatic_assert_test<sizeof(STATIC_ASSERTION_FAILURE<B>>/
boost_static_assert_typedef_##__LINE__
注意为了能够使用多个BOOST_STATIC_ASSERT,在类型命名时加入了
行号以区别。对namespace而言,因为同一namespace可能分布在多个不同的
头文件中,而不同头文件中可能在同一行使用BOOST_STATIC_ASSERT检测,
所以必须用一个namespace把断言检测隔离开,如上面例子所示。
此外,对于VC来说,在使用/ZI参数时,__LINE__宏会发生错误,
(参见MSDN中Q199057错误),好在VC会忽略typedef重复定义。
对某些不支持typedef此类特性的编译器,boost提供了使用enum的替代方案
附:boost/static_assert.hpp
//(C)CopyrightJohnMaddock2000.
//Permissiontocopy,use,modify,selland
//distributethissoftwareisgrantedprovidedthiscopyrightnoticeappears
//inallcopies.Thissoftwareisprovided"asis"withoutexpressorimplied
//warranty,andwithnoclaimastoitssuitabilityforanypurpose.
//Seehttp://www.boost.orgformostrecentversionincludingdocumentation.
/*
Revisionhistory:
02August2000
Initialversion.
*/
#ifndefBOOST_STATIC_ASSERT_HPP
#defineBOOST_STATIC_ASSERT_HPP
#include<boost/config.hpp>
#ifdef__BORLANDC__
//
//workaroundforbuggyintegral-constantexpressionsupport:
#defineBOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS
#endif
namespaceboost{
//HPaCCcannotdealwithmissingnamesfortemplatevalueparameters
template<boolx>structSTATIC_ASSERTION_FAILURE;
template<>structSTATIC_ASSERTION_FAILURE<true>{};
//HPaCCcannotdealwithmissingnamesfortemplatevalueparameters
template<intx>structstatic_assert_test{};
}
//
//Implicitinstantiationrequiresthatallmemberdeclarationsbe
//instantiated,butthatthedefinitionsare*not*instantiated.
//
//It'snotparticularlyclearhowthisappliestoenum'sortypedefs;
//botharedescribedasdeclarations[7.1.3]and[7.2]inthestandard,
//howeversomecompilersuse"delayedevaluation"ofoneormoreof
//thesewhenimplicitlyinstantiatingtemplates.Weusetypedefdeclarations
//bydefault,buttrydefiningBOOST_USE_ENUM_STATIC_ASSERTiftheenum
//versiongetsbetterresultsfromyourcompiler...
//
//Implementation:
//Bothoftheseversionsrelyonsizeof(incomplete_type)generatinganerror
//messagecontainingthenameoftheincompletetype.Weuse
//"STATIC_ASSERTION_FAILURE"asthetypenameheretogenerate
//aneyecatchingerrormessage.Theresultofthesizeofexpressioniseither
//usedasanenuminitialiser,orasatemplateargumentdependingwhichversion
//isinuse...
//Notethattheargumenttotheassertisexplicitlycasttoboolusingold-
//stylecasts:toomanycompilerscurrentlyhaveproblemswithstatic_cast
//whenusedinsideintegralconstantexpressions.
//
#if!defined(BOOST_BUGGY_INTEGRAL_CONSTANT_EXPRESSIONS)&&!defined(__MWERKS__)
#ifndefBOOST_MSVC
#defineBOOST_STATIC_ASSERT(B)/
typedef::boost::static_assert_test</
sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)>/
BOOST_JOIN(boost_static_assert_typedef_,__LINE__)
#else
//__LINE__macrobrokenwhen-ZIisusedseeQ199057
//fortunatelyMSVCignoresduplicatetypedef's.
#defineBOOST_STATIC_ASSERT(B)/
typedef::boost::static_assert_test</
sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)/
>boost_static_assert_typedef_
#endif
#else
//alternativeenumbasedimplementation:
#defineBOOST_STATIC_ASSERT(B)/
enum{BOOST_JOIN(boost_static_assert_enum_,__LINE__)/
=sizeof(::boost::STATIC_ASSERTION_FAILURE<(bool)(B)>)}
#endif
#endif//BOOST_STATIC_ASSERT_HPP
--
.生命的意义在于//____///_///_/.
.希望///___/_//////_/______★.
.工作//____////////'__`///`'_/.
.爱你的人///___////___/////__//////.
.和你爱的人//___///_____//__//____///_/.
.……//___///_____///__///____///_/@126.com.
※来源:·BBS水木清华站bbs.edu.cn·[FROM:202.114.32.225]