博客旧址
延伸读物:
个人卓见:
此人擅长逻辑推理与逐层剖析,总结一般化方法论,评论浅显易懂,条理清晰,深入浅处,谦虚话语中充满了智慧。
signal slot manager slot connection base_connection
cast trick
namespace boost
{
namespace detail
{
template<class T> struct addr_impl_ref
{
T & v_;
inline addr_impl_ref( T & v ): v_( v ) {}
inline operator T& () const { return v_; }
};
template<class T> struct addressof_impl
{
static inline T * f( T & v, long )
{
return reinterpret_cast<T*>(
&const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
//这是关键的地方,先强制转换成const volatile char &,然后去掉const属性,再取址,避免调用v的重载的operator&
}
static inline T * f( T * v, int )
{
return v;
}
};
} // namespace detail
template<class T> T * addressof( T & v )
{
#if defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) )
return boost::detail::addressof_impl<T>::f( v, 0 );
#else
return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );//vc平台走这个分支,
//调用addr_impl_ref<T>的构造函数创建一个addr_impl_ref<T>对象,
//由于boost::detail::addressof_impl<T>::f( T & v, long ),所以
//addr_impl_ref<T>对象要被强制转换成T&,触发addr_impl_ref重载的
//T& (),最终返回v的引用。
#endif
}
#endif // BOOST_UTILITY_ADDRESSOF_HPP
c++标准中有如下的规定:
An lvalue expression of type T1 can be cast to the type “reference to T2” if an expression of type “pointer
to T1” can be explicitly converted to the type “pointer to T2” using a reinterpret_cast. That is, a
reference cast reinterpret_cast<T&>(x) has the same effect as the conversion
*reinterpret_cast<T*>(&x) with the built-in & and * operators. The result is an lvalue that refers
to the same object as the source lvalue, but with a different type. No temporary is created, no copy is made,
and constructors or conversion functionsare not called.) (ISO/IEC 14882:2003(E) 5.2.10 Reinterpret cast)
大体意思就是如果一个指向T1类型的指针可以通过reinterpret_cast明确的转换成一个指向T2类型的指针,那么类型为T1的左值表达式就可以强制
转化成一个T2类型的引用,也就是说cast reinterpret_cast<T&>(x)和*reinterpret_cast<T*>(&x)是等价的,前提是在内建&和*语意下。c++
标准还强调,上述的转换结果是一个左值,和被转换的源左值引用着同一个对象,只是类型不同而已,也就是说c++标准保证,如果一个T1类型的对象x,被强制转换成了一个T2类型引用,那么T2引用是引用着T1对象,想当于*reinterpret_cast<T2*>(&x)。
所以说addressof()函数的实现是基于上述规定的。
base from member idiom
当基类初始化需要派生类的类成员变量时候,base classes are initialized in order of declaration. So moving the desired member to another base class, that is initialized before the desired base class, can ensure proper initialization.
rationale:
template <class MemberType, int UniqueId=0>
class boost::base_from_member
{
protected:
MemberType member;
//derived class member class needed for base class initialization, extracted and wrapper within base_from_member
base_from_member();
template <typename T1> explicit base_from_member(T1 x1);// param needed for MemberType class initialization.
//...
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
explicit base_from_member(T1 x1, T2 x2,...T10 x10);
};
A type that consists of nothing but Plain Old Data.
A POD type is a C++ type that has an equivalent in C, and that uses the same rules as C uses for initialization, copying, layout, and addressing.
As an example, the C declaration struct Fred x; does not initialize the members of the Fred variable x. To make this same behavior happen in C++, Fred would need to not have any constructors. Similarly to make the C++ version of copying the same as the C version, the C++ Fred must not have overloaded the assignment operator. To make sure the other rules match, the C++ version must not have virtual functions, base classes, non-static members that are private or protected, or a destructor. It can, however, have static data members, static member functions, and non-static non-virtual member functions.
The actual definition of a POD type is recursive and gets a little gnarly. Here's a slightly simplified definition of POD: a POD type's non-static data members must be public and can be of any of these types: bool, any numeric type including the various char variants, any enumeration type, any data-pointer type (that is, any type convertible to void*), any pointer-to-function type, or any POD type, including arrays of any of these. Note: data-pointers and pointers-to-function are okay, but are not. Also note that references are not allowed. In addition, a POD type can't have constructors, virtual functions, base classes, or an overloaded assignment operator.
因篇幅问题不能全部显示,请点此查看更多更全内容