以stl容器作为输入的函数模板

时间:2012-02-24 05:55:13

标签: c++ stl

我收到编译错误是以下代码。我认为这应该在c ++中有效 任何人都可以帮我理解这里有什么问题。

template < typename elem_type>
elem_type *find2( std::vector<elem_type>& vec, elem_type value) {
    for ( int i = 0; i < vec.size(); ++i) {
        if ( vec[i] == value ) {
            return &vec[i];
        }
    }
    return 0;
}
int main( int argc, char **argv) {
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    std::vector<int> vec( arr, arr+10);     
    int value = 9;
    int *ptr1 = find2(vec,value);
}

以下是编译错误

1>          d:\personal\work\find\find\find.cpp(25) : see reference to function template instantiation 'elem_type *find2<int>(std::vector<_Ty> &,elem_type &)' being compiled
1>          with
1>          [
1>              elem_type=int,
1>              _Ty=int
1>          ]

编译器是Visual Studio 11

3 个答案:

答案 0 :(得分:4)

最好使用与容器中使用的索引相同类型的变量。在这种情况下,您需要size_tsize_type。它们与向量的sizeoperator[]函数中使用的类型相对应。

for (size_t i = 0; i < myVector.size(); ++i)
{
    myVector[i]++;
}

如果需要反向迭代,只需维护一个内部索引。

for (size_t i = 0; i < myVector.size(); ++i)
{
    size_t j = myVector.size() - i - 1;
    myVector[j]++;
}

如果您需要再次执行签名数学,请维持内部演员。

for (size_t i = 0; i < myVector.size(); ++i)
{
    int j = (int)i;
    myVector[i] += j;
}

答案 1 :(得分:3)

你遇到的根本问题是混合有符号和无符号整数。您的索引变量是有符号类型,但向量的size()成员函数返回无符号类型。像这样的混合类型可能会导致错误。如果将带符号的值(如-1)分配给无符号变量,则通常会得到一个非常大的值。

迭代标准库容器的惯用方法是使用标准库迭代器。

for (std::vector<elem_type>::iterator it=vec.begin(); it<vec.end(); ++it)
{
    if ( *it == value ) {
        return &(*it);
    }
}

答案 2 :(得分:0)

在这一行中,

    for ( int i = 0; i < vec.size(); ++i ) {

您正在将已签名的int变量isize_t的未签名vec.size()结果进行比较。

编译器发出警告,因为在C ++中面对隐式提升时,这种比较是不安全的。 i被提升为size_t。如果i(假设)为负,那将产生非常大的价值,从而产生意想不到的比较结果。

一个简单的方法就是

    #include <stddef.h>
    typedef ptrdiff_t Size;
    typedef Size Index;

然后做例如。

    for ( int i = 0; i < Size( vec.size() ); ++i ) {

你可能会得到至少一个答案,建议明显更简单

    for ( size_t i = 0; i < vec.size(); ++i ) {

但这是有问题的,原因与编译器警告的相同:使用无符号整数作为数字可能会产生非常奇怪和意外的结果,错误的结果,由于隐式促销和一般从负数转换无符号,反之亦然。

甚至比上面的演员更好,定义一个countOf函数,如

    template< class Container >
    Size countOf( Container const& c ) { return v.size(); }

    template< class Elem, Size n >
    Size countOf( Elem (&)[n] ) { return n; }

然后再写

    for ( int i = 0; i < countOf( vec ); ++i ) {

最好的,忘记索引并使用迭代器:

    for ( auto it = vec.begin(); it != vec.end(); ++it ) {