我刚才发现,在Visual Studio C ++ 2010中,basic_string::append (iter, iter)
显然没有使用std::copy
来实现。
第一个问题:
现在假设我实现了自己的迭代器类型,并为我的迭代器类型优化了std::copy
的重载,以便提供更有效的逐块复制。除了重载basic_string::append
之外,还有什么方法可以让append
使用此优化吗?
basic_string::append (iter, iter)
是否有可能不进行字符复制?
第二个问题(作为我自己实施的起点):
以下是否保证有效?
std::string t ("JohnB");
std::string s;
s.reserve (10);
std::copy (t.begin (), t.end (), s.begin ());
s.push_back ('\0');
或者我应该更好地使用back_inserter
?如果我使用back_inserter
- 我怎么能避免按字符复制?
答案 0 :(得分:5)
字符串类有自己的traits类,它定义了它可以对它包含的字符执行的操作。
要复制char
,basic_string<char>
将使用std::char_traits<char>::copy
(而不是更一般的std::copy
)。这可能映射到标准C库中的memcpy
函数。
答案 1 :(得分:2)
std::basic_string<cT, ...>::append()
的定义在最终到达重载之前保持委派一些时间(21.4.6.2 [string :: append]第7段):
basic_string& append(const charT* s, size_type n);
此时显然没有剩下原始迭代器。如果您想知道输入迭代器会发生什么变化,您可能已经传递给append()
,同一段落的第17段中的重载将其删除,其中指出:
效果:相当于
append(basic_string(first, last))
。
处于某种中间状态。如果按照标准的字面说明方式实施标准库,则显然没有调用std::copy()
。
但是,无论如何,你真的无法看到std::copy()
的重载版本。
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);
}
现在,另一个有趣的是:即使这是它实现的方式,它对std::copy()
也没有真正帮助你!你不能部分地专门化std::copy()
(好吧,你不能部分地专门化任何函数模板)并且没有定义目标迭代器的类型(在上面的实现中它将是{{1}的非容量检查变体如果std::back_inserter()
是前向迭代器,则它只与InIt
相同。