当前位置: 首页 > wzjs >正文

成都网站建设四川冠辰培训机构退费纠纷一般怎么解决

成都网站建设四川冠辰,培训机构退费纠纷一般怎么解决,凡科登录入口app下载,吉林省建设厅官网查询本文根据LLVM中libcxx的实现,分析了std::any和std::variant的具体实现。 1 简介 在 C17 标准中,std::any提供了一种类型安全的方式来存储任意类型的值。它使用类型擦除(type erasure)技术实现,使得一个对象可以包含任…

  本文根据LLVM中libcxx的实现,分析了std::any和std::variant的具体实现。

1 简介

  在 C++17 标准中,std::any提供了一种类型安全的方式来存储任意类型的值。它使用类型擦除(type erasure)技术实现,使得一个对象可以包含任何类型的值而不需要提前知道该类型。std::any的使用比较简单。

#include <any>
#include <iostream>int main()
{std::cout << std::boolalpha;// any typestd::any a = 1;std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';a = 3.14;std::cout << a.type().name() << ": " << std::any_cast<double>(a) << '\n';a = true;std::cout << a.type().name() << ": " << std::any_cast<bool>(a) << '\n';// bad casttry{a = 1;std::cout << std::any_cast<float>(a) << '\n';}catch (const std::bad_any_cast& e){std::cout << e.what() << '\n';}// has valuea = 2;if (a.has_value())std::cout << a.type().name() << ": " << std::any_cast<int>(a) << '\n';// reseta.reset();if (!a.has_value())std::cout << "no value\n";// pointer to contained dataa = 3;int* i = std::any_cast<int>(&a);std::cout << *i << '\n';
}

2 实现

内存处理
  std::any的实现简单的说来就是通过一个指针存储数据和一个额外的类型信息来保留类型。

class any{union _Storage {_LIBCPP_HIDE_FROM_ABI constexpr _Storage() : __ptr(nullptr) {}void* __ptr;__any_imp::_Buffer __buf;};_HandleFuncPtr __h_ = nullptr;_Storage __s_;
};

  __h_存储不同情况对应处理的函数指针信息,__s_存储具体的内存,根据不同情况使用不同的存储方式。和常规的SSO优化类似小于某个大小的内存直接存储在栈上,否则用堆。这里的大小是对齐到3倍机器字长。

using _Buffer = aligned_storage_t<3 * sizeof(void*), alignof(void*)>;

  不同大小的对象使用不同的handler对数据进行操作,栈内存使用SmallHandle,堆内存使用LargeHandle,二者唯一的区别只是操作的内存不同,一个操作ptr,一个操作buf

template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _SmallHandler {_LIBCPP_HIDE_FROM_ABI static void*__handle(_Action __act, any const* __this, any* __other, type_info const* __info, const void* __fallback_info) {switch (__act) {case _Action::_Destroy:__destroy(const_cast<any&>(*__this));return nullptr;case _Action::_Copy:__copy(*__this, *__other);return nullptr;case _Action::_Move:__move(const_cast<any&>(*__this), *__other);return nullptr;case _Action::_Get:return __get(const_cast<any&>(*__this), __info, __fallback_info);case _Action::_TypeInfo:return __type_info();}__libcpp_unreachable();}private:_LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {typedef allocator<_Tp> _Alloc;typedef allocator_traits<_Alloc> _ATraits;_Alloc __a;_Tp* __p = static_cast<_Tp*>(static_cast<void*>(&__this.__s_.__buf));_ATraits::destroy(__a, __p);__this.__h_ = nullptr;}
};
//而对应的largeHandle的销毁不仅仅要释放对象还需要销毁内存
template <class _Tp>
struct _LIBCPP_TEMPLATE_VIS _LargeHandler {
_LIBCPP_HIDE_FROM_ABI static void __destroy(any& __this) {typedef allocator<_Tp> _Alloc;typedef allocator_traits<_Alloc> _ATraits;_Alloc __a;_Tp* __p = static_cast<_Tp*>(__this.__s_.__ptr);_ATraits::destroy(__a, __p);_ATraits::deallocate(__a, __p, 1);__this.__h_ = nullptr;}
};

  具体使用哪种类型的handle则是在构造时根据类型确定的,_IsSmallObject用来判断是否是小对象,小对象则使用_SmallHandler,否则使用_LargeHandler

template <class _Tp>
using _IsSmallObject =integral_constant<bool,sizeof(_Tp) <= sizeof(_Buffer) && alignof(_Buffer) % alignof(_Tp) == 0 &&is_nothrow_move_constructible<_Tp>::value >;template <class _Tp>
using _Handler = conditional_t< _IsSmallObject<_Tp>::value, _SmallHandler<_Tp>, _LargeHandler<_Tp>>;template <class _ValueType, class _Tp, class>
any::any(_ValueType&& __v) : __h_(nullptr) {__any_imp::_Handler<_Tp>::__create(*this, std::forward<_ValueType>(__v));
}

类型信息
  对于开启了RTTI的场景,比较简单直接返回当前对象的typeinfo即可。

  _LIBCPP_HIDE_FROM_ABI static void* __type_info() {
#  if !defined(_LIBCPP_HAS_NO_RTTI)return const_cast<void*>(static_cast<void const*>(&typeid(_Tp)));
#  elsereturn nullptr;
#  endif}

3 自己实现

  说实话LLVM的实现感觉很丑,这里通过继承来实现类型擦除会好看很多(实现其实不全,拷贝构造等都没有实现,也没有实现类型decay的情况,但是基本功能是OK的)。

#include <iostream>
#include <exception>
#include <type_traits>
#include <memory>
#include <utility>
class AnyCastError : public std::exception {
public:const char* what() const noexcept override {return "Bad cast in Any";}
};template<class T>
class AnyImpl {
public:using Buffer = std::aligned_storage_t<3 * sizeof(void*), alignof(void*)>;using IsSmallTrivialObject = std::integral_constant<bool, sizeof(T) <= sizeof(Buffer)&&alignof(Buffer) % alignof(T) == 0 &&std::is_nothrow_move_constructible<T>::value >;public:union Storage {void* ptr;Buffer buffer;Storage() : ptr(nullptr) {}~Storage() {}};
};struct HolderBase {
public:virtual ~HolderBase() = default;virtual std::unique_ptr<HolderBase> clone() const = 0;virtual const std::type_info *typeInfo() const = 0;
};template<class T>
struct Holder : public HolderBase {
public:Holder(T&& value) {if constexpr (AnyImpl<T>::IsSmallTrivialObject::value) {new(&_storage.buffer)T(std::move(value));}else {_storage.ptr = new T(std::move(value));}}~Holder() {if constexpr (AnyImpl<T>::IsSmallTrivialObject::value) {reinterpret_cast<T*>(&_storage.buffer)->~T();}else {delete static_cast<T*>(_storage.ptr);}}virtual std::unique_ptr<HolderBase> clone() const override {return std::make_unique<Holder<T>>(getValue());}T getValue() const {if constexpr (AnyImpl<T>::IsSmallTrivialObject::value) {return *reinterpret_cast<const T*>(&_storage.buffer);}else {return *static_cast<T*>(_storage.ptr);}}virtual const std::type_info* typeInfo() const override {return &typeid(T);}public:AnyImpl<T>::Storage _storage;
};class Any {
public:Any() {_holder = nullptr;}template<class T>Any(T&& v) {_holder = std::make_unique<Holder<T>>(std::forward<T>(v));}bool hasValue() const {return !!_holder;}template<class T>T getValue() {return hasValue() ? static_cast<Holder<T>*>(_holder.get())->getValue() : T();}const std::type_info* typeInfo() const {return hasValue() ? _holder->typeInfo() : &typeid(int);}
private:std::unique_ptr<HolderBase> _holder{};
};int main(int argc, char **argv){try {Any a = 42; // 存储 intstd::cout << "Value: " << a.getValue<int>() << ", Type: " << a.typeInfo()->name() << std::endl;Any b = std::string("Hello"); // 存储 stringstd::cout << "Value: " << b.getValue<std::string>() << ", Type: " << b.typeInfo()->name() << std::endl;// 测试未存储值的情况Any emptyAny;std::cout << "Has Value: " << emptyAny.hasValue() << std::endl;std::cout << "Type Info: " << emptyAny.typeInfo()->name() << std::endl;}catch (const AnyCastError& e) {std::cerr << e.what() << std::endl;}return 0;
}
http://www.dtcms.com/wzjs/524009.html

相关文章:

  • 网站开发中的文档山东济南seo整站优化公司
  • 网站域名综合查询优化软件
  • 河南住房和城乡建设厅网站特种教育培训机构报名
  • 网站建设的技术阶段软文如何推广
  • 网站收录500多页天津网站优化
  • java做电子商务网站郑州网站seo推广
  • 顺的网站建设报价上海网络营销seo
  • 营销型网站建设 高校邦邳州网站开发
  • 做新网站都需要准备什么网站seo诊断技巧
  • 织梦网站模板后台密码找回销售推广
  • 晋州专业网站建设关键词挖掘查询工具爱站网
  • 做外挂网站seo自己怎么做
  • 上海 建网站seo引擎优化专员
  • 网站的二次开发是什么意思许昌seo推广
  • 高仿服装网站建设域名查询服务器
  • 旅游网站建设与翻译什么是seo标题优化
  • 开源网站下载郑州最好的建站公司
  • 帮企业做网站的公司友情链接推广平台
  • 微网站开发 培训网络seo优化公司
  • 建设厅网站174号文磁力搜索引擎
  • 酒泉网站建设费用网络营销策划书的结构是什么
  • 专业网站建设组织阿里云免费域名
  • php网站做ios宁波seo在线优化
  • 阿里企业邮箱电话seo 优化 工具
  • 追星做网站谷歌在线搜索
  • 搜索关键词可以过得网站深圳靠谱网站建设公司
  • 网络运维工程师和网络工程师seo最好的工具
  • 软件工程文档海外广告优化师
  • 微信投票网站制作什么是软文推广
  • wordpress 菜单 固定快速优化seo软件