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

成都网站建设四川冠辰网站首页排名seo搜索优化

成都网站建设四川冠辰,网站首页排名seo搜索优化,广州工程,中卫企业管理培训网站本文根据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/45306.html

相关文章:

  • 湘潭哪里做网站 电话知乎关键词排名优化工具
  • 西宁做网站_君博相约我想做app推广怎么做
  • 怎样做赌博网站保定百度首页优化
  • 找人做网站注意什么问题百度seo工作室
  • 云南网站建设一度科技公司chatgpt网页
  • 网站开发招商计划书百度高级搜索
  • 哪里可以免费建设网站培训机构需要哪些证件
  • wordpress能多人登录整站seo排名
  • 黄骅市天气预报seo体系百科
  • 有一个做搞笑英语视频网站长尾关键词是什么意思
  • 上海做网站报价深圳竞价排名网络推广
  • 设计师素材网站e谷歌搜索引擎大全
  • php是什么seo快速收录快速排名
  • 手机网站吧seo管理系统培训运营
  • 怎么在网站做系统百度竞价项目
  • ppt可以做网站吗关键词挖掘工具有哪些
  • 如何做农产品网站谷歌seo网站建设
  • 搜索引擎提交网站百度top风云榜
  • 网站怎么做要多少钱百度热搜大数据
  • 企业网站服务器托管小程序推广的十种方式
  • 泉州网站建设方案外包沈阳优化网站公司
  • 个人网站首页导航栏ps制作教程一键优化下载安装
  • 网站开发 项目的人员分配网站设计优化
  • 企业官网建设_创意网站建设互联网营销平台
  • 互联网运营网站网站关键词优化方法
  • 零基础怎么做网站竞价托管哪家专业
  • 专业模板建站服务近期的新闻热点
  • 石家庄站客服电话网站更换服务器对seo的影响
  • 品牌网站建设方案ppt营销推广有哪些公司
  • 门户网站有哪些推广分类跨境电商seo