c – 为什么我们可以将可选参数传递给新表达式而不是删除表达式
在stackoverflow上已经就此主题提出了一些问题,但我没有看到任何解释限制删除表达式背后的基本原理.
为澄清这个问题,我试图收集事实,因为我已经在以下三个评论中理解了这些事实. 备注1:一般新表达 void* operator new(size_t,T1,T2,...,Tn); void operator delete(void*,Tn); 我们知道当程序员键入一个新表达式时: T* t = new(t1,tn) T(); (其中t1,…,tn的类型分别为T1,… Tn) T* t; void* raw = operator new(sizeof(T),t1,tn); // or T::operator new(...) try { t = new(raw) T(); } catch (...) { operator delete(raw,tn); // or T::operator delete(...) throw; } 备注2:删除表达式 – 在某些情况下是合法的 delete t; (其中t的类型是T) if (t) { t->~T(); operator delete(t); // or T::operator delete(t); } 因此我们知道用简单的语法“删除t;”我们可以隐式地自动调用任何“operator delete”,它接受与默认全局值相同的参数(它可以是默认的全局值,覆盖默认全局值的版本,或者采用相同参数的类成员版本)作为默认的全局一个). 备注3:删除表达式 – 一般非法 void operator delete(void*,Tn); 我们本来希望写一个通用的删除表达式: delete(t1,tn) t; 希望编译器自动将其替换为: if (t) { t->~T(); operator delete(t,tn); // or T::operator delete(...); } …,不幸的是我们知道“删除(t1,tn)t;”是非法的! 因此,通常建议编写模板函数,如: template<typename T> void destroy(T* t,T1 t1,Tn tn) { if(t) { p->~T(); operator delete(t,tn); // or T::operator delete(...); ?! } } 这可能有问题(您必须为每个“operator delete”定义一个,并且您必须小心,因为您无法处理全局版本和类成员版本的相同方式). 总结一下: 解决方法
请注意,由于C 11和可变参数模板,您可以将destroy写为:
// Helper to define has_operator_delete traits template <typename T,typename ...Ts> std::false_type has_operator_delete_impl(...); template <typename T,typename ...Ts> auto has_operator_delete_impl(int) -> decltype(std::declval<T>().operator delete(nullptr,std::declval<Ts>()...),std::true_type{}); // traits to know if T has operator delete(void*,Ts...) template <typename T,typename ...Ts> using has_operator_delete = decltype(has_operator_delete_impl<T,Ts...>(0)); 然后是破坏功能: template<typename T,typename ...Ts> std::enable_if_t<has_operator_delete<T,Ts...>::value> destroy(T* t,Ts&&... ts) { if (t) { t->~T(); T::operator delete(t,std::forward<Ts>(ts)...); } } template<typename T,typename ...Ts> std::enable_if_t<!has_operator_delete<T,Ts&&... ts) { if (t) { t->~T(); operator delete(t,std::forward<Ts>(ts)...); } } Live Demo 我不知道没有一般删除表达式的理由.也许它在解析某处时引入了歧义…… (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |