【问题标题】:c++ proper syntax for templated function of `std::vector<T>::iterator` [duplicate]`std::vector<T>::iterator`的模板化函数的c ++正确语法[重复]
【发布时间】:2013-08-24 12:50:49
【问题描述】:

我正在尝试编写一个模板,该模板将任何类型的向量的迭代器作为其参数。当我尝试编译以下内容时,它给了我一个no matching function call 错误。

#include <vector>

struct A { int x; };

template <class T>
void process (typename std::vector<T>::iterator begin, 
              typename std::vector<T>::iterator end)
{ for(; begin != end; begin++) { /*do_something*/ } }

int main()
{
   std::vector <A> obj;
   process(obj.begin(), obj.end());
}

【问题讨论】:

  • 为什么要限制在容器中?如果可行,请使用随机访问迭代器。
  • 简短版本:没有正确的语法 - 你不能从嵌套类型中推断出模板参数。
  • 这个问题有六万亿次重复。
  • 任何特殊原因您没有将迭代器类型本身作为模板参数,并使用 iterator_traits 提取底层值类型?
  • @MattMunson,标准算法通常采用 typename Iter 作为迭代器类型,如果不兼容,则会吐出 500 行错误。如果您想要一个好的错误,您可以使用std::iterator_traits&lt;Iter&gt;::iterator_type 或类似的东西输入static_assert

标签: c++ templates iterator


【解决方案1】:

1无法从参数类型推导出类型T

2 为什么要将函数限制为只接受 std::vector 元素的迭代器?如果你真的只想要向量元素,最好将std::vector&lt;T&gt; const&amp; 作为参数。但最好简单地采用任何迭代器参数(或任何容器参数)。


编辑好的,这是一个例子。当static_assertstd::for_each(begin,end,do_something); 相同(除了返回类型)时,您可以省略std::for_each(begin,end,do_something);

template <class It>
void process(It begin, const It end)
{
  static_assert(std::is_same<typename std::iterator_traits<It>::iterator_category,
                             std::random_access_iterator_tag>::value,
                "arguments not random access iterators");
  for (; begin != end; ++begin)
    do_something(*begin);
}

【讨论】:

  • 你能发布第二个解决方案的代码吗?
【解决方案2】:

根据 OP 的要求,见下文。您可以使用任何支持来自operator *() 的值引用的有效容器转发迭代器,即向量、双端队列、列表等。这不使用 chris 提到的静态断言逻辑,我留给你决定。

#include <iostream>
#include <iterator>

template<typename Iterator>
void process(Iterator start, Iterator stop)
{
    typedef typename std::iterator_traits<Iterator>::value_type value_type;
    for (Iterator it=start; it != stop; ++it)
    {
        const value_type& val = (*it);

        // do something with val
        std::cout << val << std::endl;
    }
}

int main()
{
    int ar[] = { 1,2,3,4,5 };

    process(std::begin(ar), std::end(ar));
    return 0;
}

【讨论】:

  • 为什么不直接使用std::cout &lt;&lt; (*it),而省略value_type 的内容?
  • @MattMunson 因为我想让你公然看看你的值类型是如何被引用的。它仅用于视觉(您的)。
猜你喜欢
  • 1970-01-01
  • 2014-01-22
  • 1970-01-01
  • 2017-03-23
  • 2016-11-07
  • 1970-01-01
  • 2022-11-21
  • 2012-11-24
  • 1970-01-01
相关资源
最近更新 更多