'Is there an example of specializing std::allocator_traits::construct?
I have the task of porting some code to c++20. Part of it is an templated allocator that handles some of the odd needs or Microsoft COM objects so we can use them in vectors. In part, it allocates/deallocates memory via CoTaskMemAlloc/CoTaskMemFree It also provides specializations of construct and destroy which have gone way in c++20.
For Example:
// 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 );
}
I am having a hard time working out how to migrate this code to c++20. If I could find an example of doing something similar that implements construct, I am pretty sure it would be obvious.
Thanks in Advance.
Solution 1:[1]
The standard has the following to say about specializing standard library templates ([namespace.std]/2):
Unless explicitly prohibited, a program may add a template specialization for any standard library class template to namespace
stdprovided 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.
The standard specifies the following behaviour for 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, invokesconstruct_at(p, std::forward<Args>(args)...).
So, if you choose to specialize std::allocator_traits<MyAlloc>::construct, it must do basically the same thing as the primary template: it will call MyAlloc::construct if possible, otherwise construct_at.
This suggests that specializing std::allocator_traits is generally not what you want to do. Instead, just like pre-C++20, you just need to make sure that MyAlloc::construct contains the logic that you want. If you want the default, you can even omit MyAlloc::construct entirely, and std::allocator_traits will take care of it.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Brian Bi |
