Title
[fund.ts.v2] basic_string_view substring constructor
Status
nad
Section
[string.view.cons]
Submitter
Evan Teran

Created on 2015-10-29.00:00:00 last changed 99 months ago

Messages

Date: 2016-03-01.20:42:47

Proposed resolution:

Not a defect. The LWG believes this missing feature is not sufficiently serious to constitute a defect.

Date: 2018-06-23.17:54:13
Change status to "LEWG"

[ 2016-03, Jacksonville ]

Change status to "LEWG"

LEWG: Do we want this constructor?

SF F N A SA

0 3 2 13 1

Date: 2016-03-01.20:42:47

Addresses: fund.ts.v2

string_view can be tremendously useful for dealing with sub-strings without copying. However, the current proposal for basic_string_view, has no constructor which provides a direct way of creating a view of a sub-string of a basic_string. Instead, we construct a view of the whole basic_string, and then as a second step create a sub-string, for example using substr. To simplify what I believe to be a common use case, I suggest adding an additional constructor.

The proposed wording for this is as follows:

template <class Allocator>
basic_string_view(const basic_string<charT, traits, Allocator>& str, size_type pos, size_type count = npos);

Throws: out_of_range if pos >= str.size().

Effects: Determines the effective length rlen of the string to reference as the smaller of count and size() - pos.

Postcondition:

data_ = str.data() + pos size_ = rlen

In other words, the result is as if constructed via: basic_string_view(basic_string_view(str).substr(pos, count));

An example implementation could look like this:

template <class Allocator>
basic_string_view(const basic_string<charT, traits, Allocator>& str, size_type pos, size_type count = npos) 
  : data_(nullptr), size_(0) 
{
  basic_string_view(str).substr(pos, count).swap(*this);
}

Note that while we have a default parameter for count, pos does not. I believe that it is best to have this as a separate overload, as opposed to default parameters on the current constructor for two reasons:

  1. The current constructor taking a basic_string does not throw, this overload can throw if pos >= str.size().

  2. This constructor performs slightly more work, it is not necessary to impose this extra work on the basic case of constructing a view of a whole string.

This has been briefly discussed in the isocpp forums. There were no obvious objections to this small improvement. Additionally, another reason to consider this addition is to provide a more consistent interface. With raw strings, we have the ability to construct a basic_string_view which is a sub-string. For example:

const char* s = "hello world";
auto v = string_view(s + 6);

But there is no constructor which easily does the same when starting with a basic_string.

Finally, As a example, consider the following (trivial) code:

void print_string(string_view v) {
  std::cout << v << '\n';
}

int main() {
  std::string s = "hello world"; // for example, we want to print the sub-string "world", without copies

  // current method:
  print_substring(string_view(s).substr(6));

  // suggested method:
  print_substring(string_view(s, 6);
}

Previous resolution [SUPERSEDED]:

This wording is relative to N4529.

  1. Insert between [string.view.cons] p5 and p6 the following sequence of paragraphs:

    template <class Allocator>
    basic_string_view(const basic_string<charT, traits, Allocator>& str, size_type pos, size_type count = npos);
    

    -?- Throws: out_of_range if pos >= str.size().

    -?- Effects: Determines the effective length rlen of the string to reference as the smaller of count and size() - pos.

    -?- Postcondition: Constructs a basic_string_view, with the postconditions in Table ?

    Table ? — basic_string_view(const basic_string<charT, traits, Allocator>&, size_type, size_type) effects
    Element Value
    data_ str.data() + pos
    size_ rlen
History
Date User Action Args
2016-03-01 20:42:47adminsetmessages: + msg7996
2016-03-01 20:42:47adminsetstatus: new -> nad
2015-11-04 20:37:27adminsetmessages: + msg7623
2015-10-29 00:00:00admincreate