首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >推断C++中模板类型的类型

推断C++中模板类型的类型
EN

Stack Overflow用户
提问于 2015-12-21 19:11:02
回答 1查看 1.2K关注 0票数 17

在为“迭代器”范围编写泛型函数时,我通常会这样做:

代码语言:javascript
复制
template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename std::decay<decltype(*first)>::type;
    ...
}

另一种方式似乎是:

代码语言:javascript
复制
template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename std::iterator_traits<Iter>::value_type;
    ...
}

还有第三个:

代码语言:javascript
复制
template <typename Iter> auto func(Iter &first, Iter &last)
{
    using IterType = typename Iter::value_type;
    ...
}

而不应用iterator_traits

从理论上讲,我的函数应该只接收firstlast形式的迭代器,第二种形式最理想(imho)是获取类型的最常用方式。但是,为了不像定义value_type那样对Iter施加限制,使用value_type是否是最通用的习惯用法?

EN

回答 1

Stack Overflow用户

发布于 2015-12-21 19:56:43

这些都不是很惯用的;您应该通过值来传递迭代器,而不是通过引用。下面是在gcc 4.9中对for_each的签名:

代码语言:javascript
复制
template<typename _InputIterator, typename _Function>
_Function
for_each(_InputIterator __first, _InputIterator __last, _Function __f)

如您所见,它是通过值传递的。您的函数在惯用用法中将不起作用:

代码语言:javascript
复制
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基本上意味着有人可以编写兼容的迭代器,但不能使用您的代码。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34394296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档