我的任务是将一些代码移植到c++20。它的一部分是一个模板分配器,它处理一些奇怪的需求或Microsoft COM对象,这样我们就可以在向量中使用它们。在某种程度上,它通过CoTaskMemAlloc/CoTaskMemFree分配/释放内存它还提供了在c++20中进行的构造和销毁的专业化。
例如:
// VARIANT
inline void CnvCoTaskAlloc<VARIANT>::construct(VARIANT* p, const VARIANT& val){
::VariantCopy( p, const_cast<VARIANT*>( &val ) );
}
inline void CnvCoTaskAlloc<VARIANT>::destroy(VARIANT* p){
::VariantClear( p );
}
我很难弄清楚如何将这些代码迁移到c++20。如果我能找到一个类似的例子来实现construct,我相信这将是显而易见的。
提前感谢。
关于专业化标准库模板([namespace.std]/2(,标准有以下几点要说:
除非明确禁止,否则程序可以将任何标准库类模板的模板专用化添加到命名空间
std
,前提是(a(添加的声明取决于至少一个程序定义的类型,并且(b(专用化满足原始模板的标准库要求。
该标准为std::allocator_traits<Alloc>::construct
([allocater.tracts.members]/5(指定了以下行为:
template<class T, class... Args> static constexpr void construct(Alloc& a, T* p, Args&&... args);
效果:如果调用格式正确,则调用
a.construct(p, std::forward<Args>(args)...)
;否则调用construct_at(p, std::forward<Args>(args)...)
。
因此,如果您选择专门化std::allocator_traits<MyAlloc>::construct
,它必须做与主模板基本相同的事情:如果可能,它将调用MyAlloc::construct
,否则调用construct_at
。
这表明专门化std::allocator_traits
通常不是你想要做的。相反,就像C++20之前一样,你只需要确保MyAlloc::construct
包含你想要的逻辑。如果你想要默认值,你甚至可以完全省略MyAlloc::construct
,std::allocator_traits
会处理它