I'm trying to create a pmr-allocated datastructure (compare code below). This however fails with an awful long error message and I can't quite track the root of it. At the end is a static_assert which says construction with an allocator must be possible if uses_allocator is true
.
As far as I can tell, std::pmr::vector is trying to call the copy constructor of profile
with an allocator which fails because 1) I didn't define a copy constructor and 2) the default copy constructor doesn't take into account allocator construction. However: Why is the copy constructor being selected in the first place? How did I urge std::pmr::vector to select the copy constructor over the default one?
#include <memory_resource>
#include <cstdio>
struct profile
{
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
profile(allocator_type allocator = {})
: allocator_{ allocator }
{}
allocator_type get_allocator() {
return allocator_;
}
allocator_type allocator_;
};
struct update
{
using allocator_type = std::pmr::polymorphic_allocator<std::byte>;
update(allocator_type allocator = {})
: profiles_{ allocator }
{
}
allocator_type get_allocator() {
return profiles_.get_allocator();
}
std::pmr::vector<profile> profiles_;
};
struct service
{
update pending_;
};
int main()
{
}
Partial error (check above link to see whole traceback):
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c /13.0.0/memory_resource:36:
In file included from /opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c /13.0.0/bits/memory_resource.h:41:
/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/13.0.0/../../../../include/c /13.0.0/bits/uses_allocator_args.h:72:8: error: static assertion failed due to requirement 'is_constructible_v<profile, const profile &, const std::pmr::polymorphic_allocator<profile> &>': construction with an allocator must be possible if uses_allocator is true
static_assert(is_constructible_v<_Tp, _Args..., const _Alloc&>,
CodePudding user response:
update(allocator_type allocator = {})
: profiles_{ allocator }
Converts allocator
to profile
and initializes profiles_
with an initializer_list containing single element, which is getting copied.
Either change {}
to ()
or make profile
constructor explicit (you might want to provide separate non-explicit default constructor in this case)