2084. basic_string use of charT*

Section: 24.3.2 [basic.string] Status: NAD Submitter: Howard Hinnant Opened: 2011-09-11 Last modified: 2016-02-10

Priority: Not Prioritized

View other active issues in [basic.string].

View all other issues in [basic.string].

View all issues with NAD status.

Discussion:

For C++11 we gave all of the containers, including basic_string new generalized pointer types:

typedef typename allocator_traits<Allocator>::pointer       pointer:
typedef typename allocator_traits<Allocator>::const_pointer const_pointer;

However, the constructors, assignment, and member functions still traffic exclusively in terms of const charT*, for example:

basic_string(const charT* s, const Allocator& a = Allocator());

Was this an oversight? Did we mean instead:

basic_string(const_pointer s, const Allocator& a = Allocator());

Rationale:

It's intentional. char_traits assumes that all elements of a string can be accessed indirect on plain pointers. So basic_string doesn't support allocators with fancy pointers or references. And we meant to do that.

Let's take the constructor example you called out:

basic_string(const charT* s, const Allocator& a = Allocator());

This constructor allows us to create a basic_string object from a string literal. If we were to change the pointer type, that would no longer be possible.

There is no issue here, as the implementation of the constructor must make a copy of the string pointed-to by the pointer 's' rather than adopt ownership of that buffer. It is that internal copy that must make use of the allocator::pointer type.

Now what about the return value of 'c_str()', should that return an allocator::pointer?

Again, the answer (I believe) is 'no' because this is the function that allows us to pass the string's contents to a legacy/OS 'C' API. It is deliberately returning a raw pointer for a reason.

There was an issue where vector::data was changed to return an allocator::pointer to the internal buffer, and this was changed back exactly because this was intended to support passing to external APIs.

Do we have a use-case where the pointer type of internal data structures of our containers (notably basic_string and vector) need to be exposed through a public API? All my current use-cases for allocator::pointer are specific to the implementation of containers themselves.

Proposed resolution: