返回迭代器时转换错误

时间:2018-01-19 10:44:24

标签: c++ iterator

我正在尝试“查找”功能。我似乎无法回来 迭代器。

template<typename T>                                                                                                  
typename T::iterator do_find(const T &v, int f)                                                                       
{                                                                                                                     
    return find(v.begin(), v.end(), f);                                                                           
}

这是我的主要内容:

int main()                                                                                                            
{                                                                                                                     
    std::vector<int> v = {1, 2, 3, 3, 4, 6};                                                                      
    std::vector<int>::iterator it;                                                                                
    it = do_find(v, 3);                                                                                           
    return 0;                                                                                                     
}      

编译时出现以下错误:

error: impossible de convertir
« std::find<__gnu_cxx::__normal_iterator<const int*, std::vector<int> >, int>((& v)->std::vector<int>::begin(), (& v)->std::vector<int>::end(), f) » de « __gnu_cxx::__normal_iterator<const int*, std::vector<int> > » vers « std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >} »

3 个答案:

答案 0 :(得分:3)

v被声明为const,然后对于std::vectorv.begin()v.end()都返回std::vector::const_iterator,然后返回{ {1}}也将是find;它无法隐式转换为std::vector::const_iterator

您可以更改返回类型,例如

std::vector::iterator

或只是

template<typename T>                                                                                                  
typename T::const_iterator do_find(const T &v, int f)                                                                       
{                                                                                                                     
    return find(v.begin(), v.end(), f);                                                                           
}

然后

template<typename T>                                                                                                  
auto do_find(const T &v, int f)                                                                       
{                                                                                                                     
    return find(v.begin(), v.end(), f);                                                                           
}

如果要通过返回的迭代器修改元素,则应将参数auto it = do_find(v, 3); 声明为非const。

v

请注意,对于template<typename T> auto do_find(T &v, int f) { return find(v.begin(), v.end(), f); } ,如果您传递非const auto,则上述do_find将返回iterator,如果您通过了vector,则返回const_iterator const vector

答案 1 :(得分:1)

vconst;意味着std::find将返回T::const_iterator。您试图返回T::iterator;并且编译器无法从const转换为非const。

修复方法是返回const_iterator或使v非常量。具体取决于你想用迭代器做什么。

答案 2 :(得分:0)

在函数中,容器被声明为常量容器

template <typename T>
typename T::iterator do_find(const T &v, int f);
                             ^^^^^^^^^^  

因此,此容器的成员函数beginend返回typename T::const_iterator类型的对象,这些对象无法隐式转换为类型。typename T::iterator

同样不清楚为什么第二个参数的类型为int,而不是类型typename T::value_type

C ++中有一个神奇的词auto可以简化函数声明并使用它的返回值。

该功能可以通过以下方式定义

template <typename T>        
auto do_find( const T &v, typename T::value_type value ){                                                                                                                     
    return std::find( v.begin(), v.end(), value );           
}

这是一个示范程序

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

template <typename T>        
auto do_find( const T &v, typename T::value_type value ){                                                                                                                     
    return std::find( v.begin(), v.end(), value );           
}

int main() 
{
    std::vector<int> v = { 1, 2, 3, 3, 4, 6 };

    auto it = do_find(v, 3);  

    if ( it != v.end() )
    {
        std::cout << *it << " is found at position "
                  << std::distance( v.cbegin(), it ) << std::endl;
    }

    return 0;
}

它的输出是

3 is found at position 2