有专门化std::allocator_traits::construct的例子吗?

Is there an example of specializing std::allocator_traits::construct?

我的任务是将一些代码移植到 c++20。它的一部分是一个模板化的分配器,可以处理一些奇怪的需求或 Microsoft COM 对象,因此我们可以在向量中使用它们。部分地,它 allocates/deallocates 内存通过 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。如果我能找到一个类似的例子来实现构造,我很确定它会很明显。

提前致谢。

该标准对专门化标准库模板有以下说明 ([namespace.std]/2):

Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace std provided that (a) the added declaration depends on at least one program-defined type and (b) the specialization meets the standard library requirements for the original template.

标准为 std::allocator_traits<Alloc>::construct ([allocator.traits.members]/5) 指定了以下行为:

template<class T, class... Args>
  static constexpr void construct(Alloc& a, T* p, Args&&... args);

Effects: Calls a.construct(p, std::forward<Args>(args)...) if that call is well-formed; otherwise, invokes construct_at(p, std::forward<Args>(args)...).

因此,如果您选择专门化 std::allocator_traits<MyAlloc>::construct,它必须做与主模板基本相同的事情:它会尽可能调用 MyAlloc::construct,否则 construct_at.

这表明专业化 std::allocator_traits 通常不是您想做的。相反,就像 pre-C++20 一样,您只需要确保 MyAlloc::construct 包含您想要的逻辑。如果你想要默认值,你甚至可以完全省略 MyAlloc::constructstd::allocator_traits 会处理它。