C++11实现的Boost库中的Any类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++11实现的Boost库中的Any类相关的知识,希望对你有一定的参考价值。
参考技术A /*******************************************************************************
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Author:Zheng Fasheng
*
* Email:zheng_fasheng@outlook.com
*
* Date:2016/9/4 20:55
*
* Summary:Declares any class from the boost library
*
******************************************************************************/
#pragma once
#include <exception>
#include <typeinfo>
#include <type_traits>
#include <typeindex>
#include <string>
namespace detail
template <bool B, class T = void>
struct disable_if_c
typedef T type;
;
template <class T>
struct disable_if_c<true, T> ;
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> ;
template<bool,class _Ty1,class _Ty2>
struct _If
// type is _Ty2 for assumed false
typedef _Ty2 type;
;
template<class _Ty1,class _Ty2>
struct _If<true, _Ty1, _Ty2>
// type is _Ty1 for assumed true
typedef _Ty1 type;
;
template<class _Ty>
struct add_reference
// add reference
typedef typename std::remove_reference<_Ty>::type& type;
;
template<>
struct add_reference<void>
// add reference
typedef void type;
;
template<>
struct add_reference<const void>
// add reference
typedef const void type;
;
template<>
struct add_reference<volatile void>
// add reference
typedef volatile void type;
;
template<>
struct add_reference<const volatile void>
// add reference
typedef const volatile void type;
;
class bad_cast
public:
explicit bad_cast(const std::string& msg )
_what = msg;
const char* what() const
return _what.data();
;
private:
std::string _what;
;
class Any
public:
Any()
: content(0)
template<typename _Ty>
Any(const _Ty & value)
: content(new holder<typename std::remove_cv< typename std::decay<const _Ty>::type>::type>(value))
Any(const Any & other)
: content(other.content ? other.content->clone() : 0)
//c++11
// Move constructor
Any(Any&& other)
: content(other.content)
other.content = 0;
// Perfect forwarding of ValueType
template<typename _Ty>
Any(_Ty&& value
, typename detail::disable_if< typename std::is_same<Any&, _Ty> >::type* = 0 // disable if value has type `any&`
, typename detail::disable_if< typename std::is_const<_Ty> >::type* = 0) // disable if value has type `const ValueType&&`
: content(new holder< typename std::decay<_Ty>::type >(static_cast<_Ty&&>(value)))
~Any()
if (content)
delete content;
content = nullptr;
public:
Any& swap(Any& rhs)
std::swap(content, rhs.content);
return *this;
Any& operator=(const Any& rhs)
Any(rhs).swap(*this);
return *this;
//c++11
//move assignement
Any& operator=(Any&& rhs)
rhs.swap(*this);
Any().swap(rhs);
return *this;
//perfect forwarding of valueType
template<class valueType>
Any& operator=(valueType&& rhs)
Any(static_cast<valueType&&>(rhs)).swap(*this);
return *this;
public: // queries
bool empty()
return !content;
void clear()
Any().swap(*this);
const std::type_info& type() const
return content ? content->type() : typeid(void);
private:
class placeholder
public:
virtual ~placeholder()
virtual const std::type_info& type() const = 0;
virtual placeholder* clone() const = 0;
;
template<typename _Ty>
class holder : public placeholder
public:
typedef _Ty value_type;
holder(const _Ty& value) :held(value)
holder(_Ty&& value)
:held(static_cast<_Ty&&>(value))
virtual const std::type_info& type() const
return typeid(value_type);
virtual placeholder* clone() const
return new holder(held);
public:
_Ty held;
private:
// intentionally left unimplemented
holder& operator=(const holder &);
;
private: // representation
template<typename _Ty>
friend _Ty * any_cast(Any *);
template<typename _Ty>
friend _Ty * unsafe_any_cast(Any *);
private:
placeholder* content;
;
inline void swap(Any & lhs, Any & rhs)
lhs.swap(rhs);
template<typename _Ty>
_Ty * any_cast(Any * operand)
return operand && operand->type() == typeid(_Ty)
? &static_cast<Any::holder< typename std::remove_cv<_Ty>::type> *>(operand->content)->held
: 0;
template<typename _Ty>
inline const _Ty * any_cast(const Any * operand)
return any_cast<_Ty>(const_cast<Any *>(operand));
template<typename _Ty>
_Ty any_cast(Any & operand)
typedef typename std::remove_reference<_Ty>::type nonref;
nonref * result = any_cast<nonref>(&operand);
if (!result)
std::string szReason = "bad any_cast : can't convert ";
szReason += operand.type().name();
szReason += " to ";
szReason += typeid(_Ty).name();
throw detail::bad_cast(szReason);
// Attempt to avoid construction of a temporary object in cases when
// `ValueType` is not a reference. Example:
// `static_cast<std::string>(*result);`
// which is equal to `std::string(*result);`
typedef typename detail::_If<
std::is_reference<_Ty>::value,
_Ty,
typename detail::add_reference<_Ty>::type
>::type ref_type;
return static_cast<ref_type>(*result);
template<typename _Ty>
inline _Ty any_cast(const Any & operand)
typedef typename std::remove_reference<_Ty>::type nonref;
return any_cast<const nonref &>(const_cast<Any &>(operand));
template<typename _Ty>
inline _Ty any_cast(Any&& operand)
static_assert(
std::is_rvalue_reference<_Ty&&>::value /*true if ValueType is rvalue or just a value*/
|| std::is_const< typename std::remove_reference<_Ty>::type >::value,
"any_cast shall not be used for getting nonconst references to temporary objects"
);
return any_cast<_Ty>(operand);
以上是关于C++11实现的Boost库中的Any类的主要内容,如果未能解决你的问题,请参考以下文章