【问题标题】:Deduce type of template type in C++在 C++ 中推断模板类型的类型
【发布时间】:2015-12-21 11:11:01
【问题描述】:

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

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 的迭代器,而第二种形式理想地(恕我直言)是获取类型的最惯用方式。但是使用typename std::decay&lt;decltype(*first)&gt;::type 是为了不对Iter 施加限制,就像定义value_type 一样吗?

【问题讨论】:

  • 我认为按值传递迭代器是惯用的。
  • 如果iterator_traits 对某事不起作用,则表示某事不是迭代器。

标签: c++ c++11


【解决方案1】:

第二个是最惯用的一个。

  • 第一个不适用于代理 (std::vector )
  • 第三个不适用于指针。

【讨论】:

    【解决方案2】:

    这些都不是非常惯用的;您应该按值传递迭代器,而不是按引用传递。这是 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 而言,此类 typedef 仅通过 iterator_traits 定义:http://en.cppreference.com/w/cpp/concept/ForwardIterator。 iterator_traits 为通用情况提供了合理的默认值,但它可以被专门化(就像指针一样)来做不同的事情。不通过 iterator_traits 基本上意味着有人可以编写一个兼容的迭代器,它适用于 STL,但不适用于您的代码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-31
      • 2015-12-14
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多