Is it safe to dereference end ()?

I have a function with the following signature:

std::string f(const char *first, const char *last) {
    std::string result;
    std::for_each(first, last, some_lambda_which_appends_to_result);
    return result;
}

and overloading for std :: string, which calls this:

std::string f(const std::string s) {
    return f(&*s.begin(), &*s.end());
    // The one below would assume that the string is not empty
    //     f(& s.front(), & s.front() + s.size());
}

However, this may be unsafe (dereferencing s.end () may be a violation of the red card in itself). Is there a safe way to get a pointer to the beginning of characters and a one-by-one pointer (two null pointers would be good in case of an empty string), or do I need to write

std::string(const std::string& s) {
    return s.empty() ? std::string() : f(& s.front(), & s.front() + s.size());
}
+2
source share
2 answers

This is unsafe for dereferencing end(). However, to achieve what you need, you can use c_str()either data():

std::string(const std::string& s) {
    return f(s.data(), s.data() + s.size());
}
+5
source

++ 14 (N4140) . [string.accessors]/1:

const charT* data() const noexcept;

1 : p , p + i == &operator[](i) i [0,size()].

, , .

end() [string.iterators]/2 :

2 : , .

"- " [iterator.requirements.general]/5:

, , , , iterator , . "-". i, *i, . , . , . [...]

, , , , , .

, std::string::end() . data() , .

, , / , , , , , .

+1

All Articles