The following code tries to emplace_back a default-initialized profile class object into a pmr vector. As vector is initialized with the allocator, it enriches the childs constructor with its own allocator argument. However, there's a second argument which is added and this is why I get a huge error:
#include <memory_resource>
#include <cstdio>
struct profile
{
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
profile(allocator_type allocator = {}) {}
};
struct update
{
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
update(allocator_type allocator = {})
: profiles_( allocator )
{
}
std::pmr::vector<profile> profiles_;
};
int main() {
update u;
u.profiles_.emplace_back();
}
For full error message check out above demo. The key part seems to be this:
stl_construct.h: In substitution of 'template<class _Tp, class ... _Args> constexpr decltype (::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [with _Tp = profile; _Args = {profile, const std::pmr::polymorphic_allocator<profile>&}]':
You can see that an argument of type profile is added additionally to the construct_at method, which is why the constructor of profile receives two arguments instead of just one (the allocator). Why is that and how can I prevent this from happening?
If your type advertises that it supports uses-allocator construction, then all of the constructors should support it.
In your case there are only implicit move and copy constructors which do not support it. The former is used by
std::vector's modifiers, e.g. byemplace_backin case a reallocation and move of elements becomes necessary. Theprofileyou are complaining about corresponds to the argument to such a move-insertion.So add overloads
and
or equivalent overloads. (Using the
std::allocator_arg_tvariant is probably a safer choice, so I would recommend you use it for your default constructors as well.)