【问题标题】:How to let the compiler deduce the types of my template iterators?如何让编译器推断出我的模板迭代器的类型?
【发布时间】:2012-07-17 08:27:44
【问题描述】:

我编写了一个函数,用于查找任何给定容器中最常见的元素(参见下面的代码),其中输入是该容器的两个 const_iterator。但是,如果我使用findMostFrequent(ivec.begin(), ivec.end()) 调用此函数,其中ivec 是vector<int>,则编译器无法推断出模板参数。使用findMostFrequent< vector<int> >(ivec.begin(), ivec.end()) 调用函数可以正常工作,但看起来很麻烦。有没有办法让编译器找出要实例化哪个模板?

template <typename T> typename T::value_type findMostFrequent(typename T::const_iterator beg, typename T::const_iterator end)
{
    // T is the type of container, T::value_type is the type which is stored in the container
    typename T::size_type current_streak = 0, max_streak = 0;
    T::value_type max_so_far;
    for (T::const_iterator iter = beg; iter != end; ++iter)
    {
        current_streak = count(beg, end, *iter);
        if ( current_streak > max_streak )
        {
            max_so_far = *iter;
            max_streak = current_streak;
        }
    }
    return max_so_far;
}

【问题讨论】:

    标签: c++ templates iterator typename


    【解决方案1】:

    编译器无法推断嵌套说明符。 “给我找一个类型,它的嵌套说明符等于我作为参数看到的类型”太复杂且通常模棱两可,无法轻松解决。相反,尝试直接从迭代器中推断出你需要知道的一切:

    template <typename IteratorType>
    typename std::iterator_traits<IteratorType>::value_type
    findMostFrequent(IteratorType beg, IteratorType end)
    {
        typename std::iterator_traits<T>::difference_type current_streak = 0, max_streak = 0;
        typename std::iterator_traits<T>::value_type max_so_far;
        for (IteratorType  iter = beg; iter != end; ++iter)
        {
            current_streak = count(beg, end, *iter);
            if ( current_streak > max_streak )
            {
                max_so_far = *iter;
                max_streak = current_streak;
            }
        }
        return max_so_far;
    }
    

    您应该使用std::iterator_traits&lt;T&gt;::value_type 而不是T::value_type 的原因是,它使您还可以为不自然定义它们的类型(例如指针)提供这些“迭代器规范”。例如,T* 实际上是这个 sn-p 的有效迭代器,但它不包含 value_type typedef/type。

    【讨论】:

    【解决方案2】:

    是的,通过使函数接受 Iter 模板参数并使用迭代器特征 (&lt;iterator&gt;) 从中推断出 T - 基本上是相反的。

    【讨论】:

      【解决方案3】:

      因为作为模板参数,您必须使用迭代器类型。下面的代码运行良好

      #include <iostream>
      #include <vector>
      
      template <typename IterType> 
      typename IterType::value_type findMostFrequent(IterType beg, IterType end)
      {
          // T is the type of container, T::value_type is the type which is stored in the container
          unsigned int current_streak = 0, max_streak = 0;
          typename IterType::value_type max_so_far;
          for (IterType iter = beg; iter != end; ++iter)
          {
              current_streak = count(beg, end, *iter);
              if ( current_streak > max_streak )
              {
                  max_so_far = *iter;
                  max_streak = current_streak;
              }
          }
          return max_so_far;
      }
      
      int main()
      {
          std::vector<int> v;
          for (unsigned int i = 0; i < 10; ++i)
              v.push_back(i);
      
          findMostFrequent(v.begin(), v.end());
      
          return 0;
      }
      

      在您的代码中,迭代器类型与向量没有任何关系,因此编译器无法推断出模板参数

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 2012-04-17
        • 1970-01-01
        相关资源
        最近更新 更多