Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Two questions about "allocator aware container"

26 views
Skip to first unread message

Daniel

unread,
Jan 26, 2016, 7:17:58 PM1/26/16
to
One, in cppreference http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer it says that

"The following rules apply to object construction:

Copy constructors of AllocatorAwareContainers obtain their instances of the
allocator by calling

std::allocator_traits<allocator_type>::select_on_container_copy_construction
on the allocator of the container being copied.

Move constructors obtain their instances of allocators by move-constructing
from the allocator belonging to the old container.

All other constructors take an allocator parameter."

So regarding copy and move constructors, how does it fit in that since C++
11, the standard library container copy and move constructors also take an
allocator parameter? Can a container that does not provide those overrides
be considered allocator aware?

Two, also in cppreference, it says that

"An AllocatorAwareContainer is a Container that holds an instance of an
Allocator and uses that instance to allocate and deallocate memory in all of
its member functions."

So suppose we have a container which internally stores (say)

std::basic_string<char_type,std::char_traits<char_type>,some_allocator_type> name_,

but as a convenience to the user exposes it as

std::basic_string<char_type> name() const
{
return std::basic_string<char_type>(name_.data(),name_.length());
}

can such a container be legitimately called allocator aware?

Thanks,
Daniel

Öö Tiib

unread,
Jan 27, 2016, 6:03:43 AM1/27/16
to
On Wednesday, 27 January 2016 02:17:58 UTC+2, Daniel wrote:
> One, in cppreference http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer it says that
>
> "The following rules apply to object construction:
>
> Copy constructors of AllocatorAwareContainers obtain their instances of the
> allocator by calling
>
> std::allocator_traits<allocator_type>::select_on_container_copy_construction
> on the allocator of the container being copied.
>
> Move constructors obtain their instances of allocators by move-constructing
> from the allocator belonging to the old container.
>
> All other constructors take an allocator parameter."
>
> So regarding copy and move constructors, how does it fit in that since C++
> 11, the standard library container copy and move constructors also take an
> allocator parameter? Can a container that does not provide those overrides
> be considered allocator aware?

No.

>
> Two, also in cppreference, it says that
>
> "An AllocatorAwareContainer is a Container that holds an instance of an
> Allocator and uses that instance to allocate and deallocate memory in all of
> its member functions."
>
> So suppose we have a container which internally stores (say)
>
> std::basic_string<char_type,std::char_traits<char_type>,some_allocator_type> name_,
>
> but as a convenience to the user exposes it as
>
> std::basic_string<char_type> name() const
> {
> return std::basic_string<char_type>(name_.data(),name_.length());
> }

Containers are objects used to store other objects and taking care of the
management of the memory used by such elements but that 'name' isn't
apparently meant as such contained element.

>
> can such a container be legitimately called allocator aware?

I think yes but I would generally expect classes with properties like 'name'
to have "has a" relation with container not "is a" relation. Otherwise the
class has different and unrelated responsibilities.

Daniel

unread,
Jan 27, 2016, 10:47:32 AM1/27/16
to
On Wednesday, January 27, 2016 at 6:03:43 AM UTC-5, Öö Tiib wrote:
>> So regarding copy and move constructors, how does it fit in that since
>> C++ 11, the standard library container copy and move constructors also take
>> an allocator parameter? Can a container that does not provide those
>> overrides be considered allocator aware?
>
> No.
>
Thanks. It appears that after many years of having avoided it, I need to read the standard itself.

Daniel

Alf P. Steinbach

unread,
Jan 27, 2016, 11:20:53 AM1/27/16
to
On 1/27/2016 1:17 AM, Daniel wrote:
> One, in cppreference http://en.cppreference.com/w/cpp/concept/AllocatorAwareContainer it says that
>
> "The following rules apply to object construction:
>
> Copy constructors of AllocatorAwareContainers obtain their instances of the
> allocator by calling
>
> std::allocator_traits<allocator_type>::select_on_container_copy_construction
> on the allocator of the container being copied.
>
> Move constructors obtain their instances of allocators by move-constructing
> from the allocator belonging to the old container.
>
> All other constructors take an allocator parameter."
>
> So regarding copy and move constructors, how does it fit in that since C++
> 11, the standard library container copy and move constructors also take an
> allocator parameter?

They don't.

A copy or move constructor /could/, in principle, take an allocator
parameter if it were defaulted, and still be a copy or move constructor,
because the requirement on a copy or move constructor's signature, just
as with a default constructor, is on how it can be called.

The text above describes how copy and move constructors for an allocator
aware container obtain allocator instances for the new instance: it's
not via a parameter.


> Can a container that does not provide those overrides
> be considered allocator aware?

Yes, there are no such constructors.


> Two, also in cppreference, it says that
>
> "An AllocatorAwareContainer is a Container that holds an instance of an
> Allocator and uses that instance to allocate and deallocate memory in all of
> its member functions."
>
> So suppose we have a container which internally stores (say)
>
> std::basic_string<char_type,std::char_traits<char_type>,some_allocator_type> name_,
>
> but as a convenience to the user exposes it as
>
> std::basic_string<char_type> name() const
> {
> return std::basic_string<char_type>(name_.data(),name_.length());
> }
>
> can such a container be legitimately called allocator aware?

Yes, if it provides a means to specify the allocator type. You can't
make the class less allocator aware by adding convenience methods.
Usually the allocator type is a defaulted template parameter.

All that said, I find the machinery described in the quoted text,
repulsive in a way. It's very kludgy. Unclean.

There are probably good historical reasons for it but ouch!


Cheers & hth.,

- Alf

Alf P. Steinbach

unread,
Jan 27, 2016, 11:25:14 AM1/27/16
to
On 1/27/2016 5:20 PM, Alf P. Steinbach wrote:
>
> The text above describes how copy and move constructors for an allocator
> aware container obtain allocator instances for the new instance: it's
> not via a parameter.

I meant, not /as/ a parameter, that there's no allocator parameter.


Cheers,

- Alf

Daniel

unread,
Jan 27, 2016, 11:53:45 AM1/27/16
to
On Wednesday, January 27, 2016 at 11:20:53 AM UTC-5, Alf P. Steinbach wrote:
> On 1/27/2016 1:17 AM, Daniel wrote:
> > So regarding copy and move constructors, how does it fit in that since C++
> > 11, the standard library container copy and move constructors also take an
> > allocator parameter?
>
> They don't.
>

They do :-)

> A copy or move constructor /could/, in principle, take an allocator
> parameter if it were defaulted, and still be a copy or move constructor,
> because the requirement on a copy or move constructor's signature, just
> as with a default constructor, is on how it can be called.
>
> The text above describes how copy and move constructors for an allocator
> aware container obtain allocator instances for the new instance: it's
> not via a parameter.
> .

That text is incomplete.

Check Allocator-aware container requirements,
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf
Table 99.

Post it's require that get_allocator() == the passed allocator parameter, if one is provided.

Daniel




Alf P. Steinbach

unread,
Jan 27, 2016, 12:31:27 PM1/27/16
to
On 1/27/2016 5:53 PM, Daniel wrote:
> On Wednesday, January 27, 2016 at 11:20:53 AM UTC-5, Alf P. Steinbach wrote:
>> On 1/27/2016 1:17 AM, Daniel wrote:
>>> So regarding copy and move constructors, how does it fit in that since C++
>>> 11, the standard library container copy and move constructors also take an
>>> allocator parameter?
>>
>> They don't.
>>
>
> They do :-)

Uhm, not sure how you arrive at that conclusion, so not sure what to
explain.

Regarding terminology, a “copy constructor” for class T is one that can
be called with a single argument of type T, where the formal argument
type is one 4 allowed by the standard. It's not enough that a
constructor copies a T instance. It must be callable with single arg.

And ditto for move constructor.

Let's consider a concrete example, std::vector.

C++11 §23.3.6.1 provides a class declaration, with the following
constructors that can be passed a std::vector as first argument:


vector(const vector<T,Allocator>& x);
vector(vector&&);

vector(const vector&, const Allocator&);
vector(vector&&, const Allocator&);

The first one is the copy constructor. It has /a single formal argument/
of vector type. The standard's requirement of a copy constructor for
class T is that it can be called with a single argument of type T. The
standard lists 4 possible formal argument types for that first argument,
and those include pass by ref to const, as above.

The second one is the move constructor.

The third and fourth have allocator arguments. They are neither copy nor
move constructors, because they do not conform to the requirements on a
copy or move constructor. They can't be called with single argument.

Summing up, AFAIK there are no copy or move constructors in the standard
library with allocator as extra argument.

If there were then, as I mentioned in the original response, the
allocator argument would have to be defaulted.

Daniel

unread,
Jan 27, 2016, 1:11:49 PM1/27/16
to
On Wednesday, January 27, 2016 at 12:31:27 PM UTC-5, Alf P. Steinbach wrote:
> On 1/27/2016 5:53 PM, Daniel wrote:
> > On Wednesday, January 27, 2016 at 11:20:53 AM UTC-5, Alf P. Steinbach wrote:
> >> On 1/27/2016 1:17 AM, Daniel wrote:
> >>> So regarding copy and move constructors, how does it fit in that since C++
> >>> 11, the standard library container copy and move constructors also take an
> >>> allocator parameter?
> >>
> >> They don't.
> >>
> >
> > They do :-)
>
> Uhm, not sure how you arrive at that conclusion, so not sure what to
> explain.
>
You're right.

I was asking about these constructors

vector(const vector&, const Allocator&);
vector(vector&&, const Allocator&);

I took your statement "there are no such constructors" to mean that such constructors did not exist, but I see you were just pointing out that they were not by definition copy or move constructors.

My question was whether these were required in order for a container to be "allocator aware", and as Öö Tiib replied, the answer is yes.

Thanks,
Daniel
0 new messages