sql网站模板,优化网站搭建,信息咨询公司网站源码,怎样用dw做新闻发布网站小问题也会影响设计的思路#xff0c;某个问题或某种case的探讨有助于理解设计的初衷。 声明#xff1a;以下_Tp/Tp都是指要放入std::any的对象的类型。 它要求_Tp is_copy_constructible, 仅仅是因为有很多函数的实现调用了Tp的拷贝构造函数吗#xff1f;比如说上节提到的初…小问题也会影响设计的思路某个问题或某种case的探讨有助于理解设计的初衷。 声明以下_Tp/Tp都是指要放入std::any的对象的类型。 它要求_Tp is_copy_constructible, 仅仅是因为有很多函数的实现调用了Tp的拷贝构造函数吗比如说上节提到的初始化函数
any(_Tp __value) //调用_Tp copy ctor/move ctor
any(in_place_type_t_Tp, _Args... __args) //调用_Tp parameterized ctor
any(in_place_type_t_Tp, initializer_list_Up __il, _Args... __args) //调用_Tp parameterized ctoroperator(_Tp __rhs) //先构造临时any对象(调用第一种情况)再move给*this
第一种case如果__value是左值则最终会调用到_Tp copy ctor:
_Manager_internal templatetypename _Upstatic void_S_create(_Storage __storage, _Up __value){void* __addr __storage._M_buffer;::new (__addr) _Tp(std::forward_Up(__value));}_Manager_external templatetypename _Upstatic void_S_create(_Storage __storage, _Up __value){__storage._M_ptr new _Tp(std::forward_Up(__value));}
简单写个例子证实我们的推断 1 #include any2 #include iostream3 using namespace std;45 int main()6 {7 class Person{8 private:9 int _age;10 int _height;11 public:12 Person(){coutdefault ctorendl;}1314 Person(int age,int h):_age(age),_height(h){15 coutparameterized ctorendl;16 }17 Person(const Person o): _age(o._age), _height(o._height){ coutcopy ctorendl; }1819 Person operator(const Person o){20 if (this ! o) {21 _age o._age;22 _height o._height;23 coutassignmentendl;24 }25 return *this;26 }2728 Person(Person o) noexcept : _age(std::move(o._age)), _height(std::move(o._height)) {29 o._age 0;30 o._height 0;31 std::cout move ctor std::endl;32 }
3334 Person operator(Person o) noexcept {35 if (this ! o) {36 _age std::move(o._age);37 _height std::move(o._height);38 o._age 0;39 o._height 0;40 std::cout move assignment std::endl;41 }42 return *this;43 }4445 void print(){46 coutage:_age height:_heightendl;47 }48 };49 any a1{ Person(1,2) }; //call Persons move ctor50 any a2(a1); //call Persons copy ctor51 cout----------------endl;5253 Person p Person(1,2);54 any a3(p); //call Persons copy ctor55 cout----------------endl;5657 any a4(std::in_place_typePerson, 3, 4); //call Persons parameterized ctor58 Person p4 std::any_castPerson(a4); //ref, no copy of Person59 p4.print();6061 return 0;62 }输出如下 parameterized ctor move ctor copy ctor ---------------- parameterized ctor copy ctor ---------------- parameterized ctor age:3 height:4 50、54行都调用了Persons copy ctor.
50行any copy
54行由一个左值Person对象初始化一个any对象
但是不是所有暴露出来的接口都需要Tp支持copy constructible哪是不是不支持就无法完成初始化获取回来数据 这种有意义的操作哪显然不是请看57-59行。
57行调用Tp的parameterized ctor构造了一个any对象实际没调用Tp的copy ctor, 但实现中依然要求Tp是copy constructible的, 如下所示 template typename _Tp, typename... _Args, typename _VTp decay_t_Tp,typename _Mgr _Manager_VTp,__any_constructible_t_VTp, _Args... falseexplicitany(in_place_type_t_Tp, _Args... __args): _M_manager(_Mgr::_S_manage){_Mgr::_S_create(_M_storage, std::forward_Args(__args)...);}template typename _Res, typename _Tp, typename... _Argsusing __any_constructible enable_if__and_is_copy_constructible_Tp,is_constructible_Tp, _Args...::value,_Res;template typename _Tp, typename... _Argsusing __any_constructible_t typename __any_constructiblebool, _Tp, _Args...::type;
看到enable_if__and_is_copy_constructible_Tp没正是这厮
不相信的话我们做个试验把我们上面例子中的第17行改为copy ctor deleted. 删除49~56行
Person(const Person o)delete;
编译报错 好了我们修改一下any源代码把198行注释掉以期盼甩掉对Tp copy ctor的限制
196 template typename _Tp, typename... _Args, typename _VTp decay_t_Tp,
197 typename _Mgr _Manager_VTp
198 //__any_constructible_t_VTp, _Args... false
199 explicit
200 any(in_place_type_t_Tp, _Args... __args)
201 : _M_manager(_Mgr::_S_manage)
202 {
203 _Mgr::_S_create(_M_storage, std::forward_Args(__args)...);
204 }编译竟然又报错 明明调用不到Tp的copy ctor啊, 为何报错
让我们仔细看下589行
573 any::_Manager_internal_Tp::
574 _S_manage(_Op __which, const any* __any, _Arg* __arg)
575 {
576 // The contained object is in _M_storage._M_buffer
577 auto __ptr reinterpret_castconst _Tp*(__any-_M_storage._M_buffer);
578 switch (__which)
579 {
580 case _Op_access:
581 __arg-_M_obj const_cast_Tp*(__ptr);
582 break;
583 case _Op_get_type_info:
584 #if __cpp_rtti
585 __arg-_M_typeinfo typeid(_Tp);
586 #endif
587 break;
588 case _Op_clone:
589 ::new(__arg-_M_any-_M_storage._M_buffer) _Tp(*__ptr);虽然运行时没用到但是编译依然要编译这一行编译::new ... Person(const Person)肯定报错啊因为没有这个函数这下好了不管你用到没用到Tp的copy ctor, 为了编译通过你的Tp必须要有copy ctor了躲不过了
_Manager_external也一样躲不过
622 case _Op_clone:
623 __arg-_M_any-_M_storage._M_ptr new _Tp(*__ptr);
624 __arg-_M_any-_M_manager __any-_M_manager;最后不要忘了把any源代码里的改动恢复回来。