【问题标题】:What type does std::find_if_not() return?std::find_if_not() 返回什么类型?
【发布时间】:2013-12-12 09:20:46
【问题描述】:

我在做C++ Primer一书中的练习时被卡住了,它是:

练习 10.24:使用 bind 和 check_size 查找 a 中的第一个元素 值大于指定长度的整数向量 字符串值。

我的代码:

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>

bool check_size(const std::string &s, std::string::size_type sz)
{
   return s.size() > sz;
}

std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s);

int main(){return 0;}

std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s)
{
    auto it= std::find_if_not(v.begin(), v.end(),std::bind(check_size,s,std::placeholders::_1));
    return it;
}

尝试编译时,编译器报错:

error: could not convert 'it' from '__gnu_cxx::__normal_iterator<const int*, std::vector<int> >' to 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}'

为了了解发生了什么,我转向标题 *stl_algo.h*,我猜 std::find_if_not 是在其中定义的。那里的评论说:

@return @p 范围内的第一个迭代器@c i [_first,_last)

这个函数的定义:

template<typename _InputIterator, typename _Predicate>
inline _InputIterator
find_if_not(_InputIterator __first, _InputIterator __last,
    _Predicate __pred)
{
  // concept requirements
  __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
  __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
      typename iterator_traits<_InputIterator>::value_type>)
  __glibcxx_requires_valid_range(__first, __last);
  return std::__find_if_not(__first, __last, __pred);
}

似乎返回类型应该与参数相同。但是为什么编译器会这样抱怨呢?如何解决这个错误?谢谢。

【问题讨论】:

  • iteratorconst_iterator 不同。您无法从常量向量中获得iterator
  • 又一次滥用autoauto 适用于 for 循环的控制变量,其中声明的变量在 for 循环之外没有作用域,但它的使用更普遍应该被视为反模式。
  • @chris 谢谢..你是对的..
  • @JamesKanze 所以..你的意思是这样更好吗: std::vector::iterator it= std::find_if_not(v.begin(), v.end (),std::bind(check_size,s,std::placeholders::_1)); ?如果是这样,你能告诉我更多为什么这种方式更好吗?刚开始学C++,很需要这样的建议。
  • @AlanWang 在这种情况下,肯定是的。 类型在这里很重要(你会在初始化it 时得到错误),你应该指定它,即使它有点冗长。您想使用auto 的唯一时间是在手写循环中,其中类型不会传播,并且变量仅用作经典迭代器(与container.end() 比较,取消引用,递增)。跨度>

标签: c++ algorithm c++11 stl iterator


【解决方案1】:
std::vector<int>::iterator
find_first_bigger(const std::vector<int> &v, const std::string &s);
                   ^^

你的向量是常量。所以你会得到一个std::vector&lt;int&gt;::const_iterator。 如果不是 const,你会得到一个 std::vector&lt;int&gt;::iterator

【讨论】:

    【解决方案2】:

    通知

    //...
    inline _InputIterator
    find_if_not(_InputIterator __first, _InputIterator __last,
        _Predicate __pred)
    //...
    

    返回它作为参数接收的相同类型的迭代器。

    由于您传递了const std::vector&lt;int&gt; &amp;v,因此您必须返回const_iterator

    std::vector<int>::const_iterator
    find_first_bigger(const std::vector<int> &v, const std::string &s);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多