例如,参考cplusplus.com的此代码段:
template <class InputIterator, class T>
typename iterator_traits<InputIterator>::difference_type
count(InputIterator first, InputIterator last, const T& val)
{
typename iterator_traits<InputIterator>::difference_type ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}
问题是为什么要iterator_traits
在这种情况下使用而不是采用另一个模板参数,如下所示:
template <class InputIterator, class T, class DiffType>
DiffType count(InputIterator first, InputIterator last, const T& val)
{
DiffType ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}
您在注释中提出的建议(使函数接受另一个模板参数)将无法按预期工作。这是您建议的代码:
template <class InputIterator, class T, typename DiffType>
DiffType count(InputIterator first, InputIterator last, const T& val)
{
DiffType ret = 0;
while (first!=last) {
if (*first == val)
++ret;
++first;
}
return ret;
}
此代码的问题是,它不再编译:
std::vector<int> v = /* ... */;
auto numElems = count(v.begin(), v.end(), 137); // <--- Error!
这里的问题是,为了调用功能模板,每个模板参数要么必须可以从参数类型中推导出,要么必须由调用者明确指定。在这里,DiffType
不能从参数类型推断出类型(可以从两个参数推断出InputIterator
andT
类型,但是仅从签名就没有上下文),因此该调用将因编译器错误而失败。这里使用的std::iterator_traits
是一种通用的模板模式,用于从迭代器类型本身中提取有关迭代器的信息。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句