I just figured out that in Visual Studio C++ 2010, basic_string::append (iter, iter)
is, obviously, not implemented by making use of std::copy
.
First question:
Now suppose I implement my own iterator type, together with an optimized overloading of std::copy
for my iterator type in order to provide more efficient block-wise copying. Is there any way to get basic_string::append
to make use of this optimization, apart from overloading append
as well?
Is there any chance that basic_string::append (iter, iter)
does not do character-wise copying?
Second question (as a starting point for my own implementation):
Is the following guaranteed to be valid?
std::string t ("JohnB");
std::string s;
s.reserve (10);
std::copy (t.begin (), t.end (), s.begin ());
s.push_back ('\0');
or should I better use a back_inserter
? If I use a back_inserter
-- how can I avoid character-wise copying?
The string class has its own traits class that defines the operations it can do on the characters it contains.
To copy char
s, basic_string<char>
will use std::char_traits<char>::copy
(instead of the more general std::copy
). That probably maps to the memcpy
function in the standard C library.
The definition of std::basic_string<cT, ...>::append()
keeps delegating a few time before it eventually arrives at the overload (21.4.6.2 [string::append] paragraph 7):
basic_string& append(const charT* s, size_type n);
At this point there is clearly none of the original iterators left. In case you wonder what happens to the input iterator you may have passed to append()
, the got removed by the overload in paragraph 17 of the same paragraph which states:
Effects: Equivalent to
append(basic_string(first, last))
.
at some intermediate state. If the standard library is implemented the way as it is literally stated by the standard there is clearly no call to std::copy()
.
You wouldn't really be able to see your overloaded version of std::copy()
anyway, though. What the library may do is the moral equivalent of
template <typename InIt>
std::basic_string<cT, ...>& std::basic_string<cT, ...>::append(InIt begin, InIt end) {
if (is_forward_iterator<begin>::value) {
this->reserve(this->size() + std::distance(begin, end));
}
std::copy(begin, end, back_inserter_without_capacity_check<InIt>(*this);
}
Now, the other interesting bit is: Even if this is how it implemented, it doesn't really help you with respect to std::copy()
! You cannot partially specialize std::copy()
(well, you can't partially specialize any function template) and the type of target iterator is not defined (in the above implementation it would be a non-capacity checking variant of std::back_inserter()
if InIt
is a forward iterator and otherwise it would just be the same as std::back_inserter()
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.