在为“迭代器”范围编写泛型函数时,我通常会这样做:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename std::decay<decltype(*first)>::type;
...
}
另一种方式似乎是:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename std::iterator_traits<Iter>::value_type;
...
}
还有第三个:
template <typename Iter> auto func(Iter &first, Iter &last)
{
using IterType = typename Iter::value_type;
...
}
而不应用iterator_traits
。
从理论上讲,我的函数应该只接收first
和last
形式的迭代器,第二种形式最理想(imho)是获取类型的最常用方式。但是,为了不像定义value_type
那样对Iter
施加限制,使用value_type
是否是最通用的习惯用法?
发布于 2015-12-21 19:56:43
这些都不是很惯用的;您应该通过值来传递迭代器,而不是通过引用。下面是在gcc 4.9中对for_each的签名:
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)
如您所见,它是通过值传递的。您的函数在惯用用法中将不起作用:
func(v.begin(), v.end()); // error, binding non-const ref to rvalue!
此外,通过iterator_traits不仅仅是习惯用法,它基本上是必需的。就STL而言,这样的typedefs仅通过iterator_traits:http://en.cppreference.com/w/cpp/concept/ForwardIterator定义。iterator_traits为一般情况提供了合理的默认值,但它可以专门化(就像指针一样)来做不同的事情。不通过iterator_traits基本上意味着有人可以编写兼容的迭代器,但不能使用您的代码。
https://stackoverflow.com/questions/34394296
复制相似问题