unspecified-bool-type

本文详细解析了safeboolidiom的概念及其在C++中的应用,解释了为何在某些情况下使用operator bool()不是一个好的选择,并探讨了如何通过使用safeboolidiom来避免潜在的问题。

类boost::scoped_ptr的源码中有如下声明:

operator unspecified-bool-type() const;
    这是个到unspecified-bool-type类型的隐式转换函数,它可以在Boolean上下文中测试一个智能指针。如果shared_ptr保存着一个有效的指针,返回值为True;否则为false。注意,转换函数返回的类型是不确定的。把返回类型当成bool用会导致一些荒谬的操作,所以典型的实现采用了safe bool idiom,它很好地确保了只有可适用的Boolean测试可以使用。这个函数不会抛出异常。


safe bool idiom

这个就是传说中的布尔类型转换操作符号:
当我们使用if(p) 这个来检测一个p(可以是一个变量也可以是一个自己定义的类型),如果是变量很简单,如果是类型就要使用到类型的BOOL 类型转换操作符号了
safe bool idiom的起源来自于这样子的一种用法:if( obj ) { ... },对于obj是built-in类型,那自然行得通,但是对于一个class或者struct就并不总是可以了。当然可以通过这样子的用法来代替:if( obj.is_valid() ){},问题很明显,第一烦琐,第二通用性不够,也许应该使用obj.Valid()或者obj.Empty()之类的,这与template结合起来考虑是尤其是个问题。因此我们希望有一个解决方案是的我们直接可以写下if(obj)这样的语句。
初初一想,这很简单,重载operator bool不就可以了,又或者重载operator void*?是的,这两个方法确确实实使得我们可以使用if(obj)这样的语句了,但是仔细推敲的话就会发现有很多问题。
再看一个问题:
第一次看到while(cin)这种循环条件,把他改成了while(1)效果也是一样,那到底两个有什么区别呢?
while后面都是对循环的条件的检测,cin不是bool,cin是个istream类型的对象,而istream重载了operator   void*(),指针类型是可以进行判断的,0指针为false,非0为true。
至于为什么用void*而不用bool,是bool几乎可以隐式转成其它各种类型,因此容易引发各种让人奇怪的转换甚至隐藏程序错误,比如转换成char: 
char   c   =   cin; 
再比如: 
putchar(cin); 
这看上去太奇特了,所以operator   bool()不好,改用operator   void*()了。

看这里:http://www.artima.com/cppsource/safeboolP.html


参考:

http://blog.youkuaiyun.com/hityct1/article/details/3923074

http://www.cnblogs.com/hujian/archive/2012/12/10/2810754.html

#ifndef _AP4_MPEG2_PARSER_H_ #define _AP4_MPEG2_PARSER_H_ /*---------------------------------------------------------------------- | includes +---------------------------------------------------------------------*/ #include "Ap4Types.h" #include "Ap4Utils.h" #include "Ap4Results.h" #include "Ap4DataBuffer.h" #include "Ap4Mpeg2NalParser.h" /*---------------------------------------------------------------------- | constants +---------------------------------------------------------------------*/ const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_UNSPECIFIED = 0xB0; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_PICTURE = 0x00; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_USER_DATA = 0xB2; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_SEQUENCE_HEADER = 0xB3; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_SEQUENCE_ERROR = 0xB4; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_EXTENSION = 0xB5; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_SEQUENCE_END_CODE = 0xB7; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_GROUP_START_CODE = 0xB8; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_SYSTEM_BEGIN = 0xB9; const unsigned int AP4_MPEG2_NAL_UNIT_TYPE_SYSTEM_END = 0xFF; /*---------------------------------------------------------------------- | enums +---------------------------------------------------------------------*/ typedef enum { AP4_MPEG2_PIC_TYPE_IFRAME = 0b001, AP4_MPEG2_PIC_TYPE_PFRAME = 0b010, AP4_MPEG2_PIC_TYPE_BFRAME = 0b011, AP4_MPEG2_PIC_TYPE_BUTT } AP4_MPEG2_PIC_TYPE; /*---------------------------------------------------------------------- | types +---------------------------------------------------------------------*/ struct AP4_Mpeg2SequenceHeader { AP4_Mpeg2SequenceHeader(); void GetInfo(unsigned int& width, unsigned int& height, float& fps); AP4_DataBuffer raw_bytes; unsigned int horizontal_size_value; unsigned int vertical_size_value; unsigned char aspect_ratio_information; unsigned char frame_rate_code; unsigned int bit_rate_value; unsigned char marker_bit; unsigned int vbv_buffer_size_value; unsigned char constrained_parameters_flag; unsigned char load_intra_quantiser_matrix; unsigned char load_non_intra_quantiser_matrix; }; struct AP4_Mpeg2PictureHeader { AP4_Mpeg2PictureHeader(); unsigned int temporal_reference; unsigned char picture_coding_type; unsigned int vbv_delay; }; /*---------------------------------------------------------------------- | AP4_Mpeg2FrameParser +---------------------------------------------------------------------*/ class AP4_Mpeg2FrameParser { public: // types struct AccessUnitInfo { AccessUnitInfo():nal_units(NULL), is_iframe(false), decode_order(0), display_order(0), picture_type(AP4_MPEG2_PIC_TYPE_BUTT) {} AP4_DataBuffer* nal_units; bool is_iframe; AP4_UI32 decode_order; AP4_UI32 display_order; AP4_UI32 picture_type; void Reset(); }; // methods AP4_Mpeg2FrameParser(); ~AP4_Mpeg2FrameParser(); void Reset(void); /** * Feed some data to the parser and look for the next NAL Unit. * * @param data Pointer to the memory buffer with the data to feed. * @param data_size Size in bytes of the buffer pointed to by the * data pointer. * @param bytes_consumed Number of bytes from the data buffer that were * consumed and stored by the parser. * @param access_unit_info Reference to a AccessUnitInfo structure that will * contain information about any access unit found in the data. If no * access unit was found, the nal_units field of this structure will be an * empty array. * @param eos Boolean flag that indicates if this buffer is the last * buffer in the stream/file (End Of Stream). * * @result: AP4_SUCCESS is the call succeeds, or an error code if it * fails. * * The caller must not feed the same data twice. When this method * returns, the caller should inspect the value of bytes_consumed and * advance the input stream source accordingly, such that the next * buffer passed to this method will be exactly bytes_consumed bytes * after what was passed in this call. After all the input data has * been supplied to the parser (eos=true), the caller also should * this method with an empty buffer (data=NULL and/or data_size=0) until * no more data is returned, because there may be buffered data still * available. * * When data is returned in the access_unit_info structure, the caller is * responsible for freeing this data by calling AccessUnitInfo::Reset() */ AP4_Result Feed(const void* data, AP4_Size data_size, AP4_Size& bytes_consumed, AccessUnitInfo& access_unit_info, bool eos=false); AP4_Result Feed(const AP4_UI08* nal_unit, AP4_Size nal_unit_size, AccessUnitInfo& access_unit_info, bool last_unit=false); AP4_Mpeg2SequenceHeader* GetSequenceHeader() { return &m_SequenceHeader; } const AP4_Mpeg2PictureHeader* GetPictureHeader() { return &m_PictureHeader; } private: // methods AP4_Result ParseSequenceHeader(const unsigned char* data, unsigned int data_size, AP4_Mpeg2SequenceHeader& sh); AP4_Result ParsePictureHeader(const AP4_UI08* data, unsigned int data_size, AP4_Mpeg2PictureHeader& slice_header); void CheckIfAccessUnitIsCompleted(AccessUnitInfo& access_unit_info); AP4_Result AppendNalUnitData(const unsigned char* data, unsigned int data_size); bool CheckIfSequenceHeaderDuplicated(const unsigned char* data, unsigned int data_size); // members AP4_Mpeg2NalParser m_NalParser; AP4_Mpeg2SequenceHeader m_SequenceHeader; // only updated on new VLC NAL Units AP4_Mpeg2PictureHeader m_PictureHeader; unsigned int m_AccessUnitVclNalUnitCount; // accumulator for NAL unit data unsigned int m_TotalNalUnitCount; unsigned int m_TotalAccessUnitCount; AP4_DataBuffer m_AccessUnitData[2]; unsigned int m_ActiveAccessUnitIndex; unsigned int m_LastIframeTotalAUCount; }; #endif // _AP4_MPEG2_PARSER_H_ 注释上述代码
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值