简体   繁体   中英

C++ List Iterator to Function

I'm trying to pass the iterator to a separate function to then do something with the element at that location in the list.

This is not working for me.

#include <list>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    void doSomething(iterator::<int> *it);

    list<int> intList;

    intList.push_back(10);
    intList.push_back(20);
    intList.push_back(10);
    intList.push_back(30);

    list<int>::iterator it;



    for (it = intList.begin(); it != intList.end(); it++)
    {
        if (*it == '10')
            doSomething(*it);
    };

    void doSomething(iterator <int> *it)
    {
        (*it) = 200;
    };
}

iterator isn't a standalone type in itself. It's just a typedef (it could be more than that. But we may safely assume that for this question)

list<int>::iterator is a separate type and so is vector<int>::iterator without any common class in hierarchy. All functions that accept an iterator are typically templatized functions where the template type having the constraint to satisfy the requirements of iterator .

For your case you will have to declare doSomething as either:

void doSomething(list::iterator <int> it);  // will only work with std::list iterators

Or the way most STL functions/containers accept iterators

template<typename Iterator>
void doSomething(Iterator it); // generic. Will work with any container whose iterator has an overload for * operator

In either case at the caller side you can do

for (it = intList.begin(); it != intList.end(); it++)
{
    if (*it == 10)
       doSomething(it);
};
  • itetator won't automatically mean iterator for std::list .
  • You cannot define functions inside functions: the GCC extension is only available for C, not for C++.
  • Match the types by using unary & operator (take address) and unary * operator (dereference).

Corrected code (at least it compiles):

#include <list>
#include <iostream>

using namespace std;

int main(int argc, char *argv[])
{
    void doSomething(list<int>::iterator *it);

    list<int> intList;

    intList.push_back(10);
    intList.push_back(20);
    intList.push_back(10);
    intList.push_back(30);

    list<int>::iterator it;

    for (it = intList.begin(); it != intList.end(); it++)
    {
        if (*it == '10')
            doSomething(&it);
    }

}

void doSomething(list<int>::iterator *it)
{
    *(*it) = 200;
}

To make this code better:

  • Declaring functions locally is not common.
  • Using reference might be better.
  • Using multi-character character constant looks weird. You may want simple integer 10 instead of '10' , which may be 12592 (0x3130). Note that value of multi-character character constant is implementation-defined.

Code that seems better:

#include <list>
#include <iostream>

using namespace std;

 void doSomething(list<int>::iterator &it);

int main(int argc, char *argv[])
{

    list<int> intList;

    intList.push_back(10);
    intList.push_back(20);
    intList.push_back(10);
    intList.push_back(30);

    list<int>::iterator it;

    for (it = intList.begin(); it != intList.end(); it++)
    {
        if (*it == 10)
            doSomething(it);
    }

}

void doSomething(list<int>::iterator &it)
{
    (*it) = 200;
}
#include <list>
#include <iostream>

using namespace std;

void doSomething(list<int>::iterator *it)
    {
        *(*it) = 200;
    }

int main(int argc, char *argv[])
{

    list<int> intList;

    intList.push_back(10);
    intList.push_back(20);
    intList.push_back(10);
    intList.push_back(30);

    list<int>::iterator it;



    for (it = intList.begin(); it != intList.end(); it++)
    {
        if (*it == '10')
            doSomething(&it);
    }   
}

Please make the doSomething function outside of main(). Also your argument in the function is wrong. iterator serves as a typedef and its kinda pointer in some way. You pass a ppointer as an argument , you need to take the address of your pointer with this symbol '&'.

Best-ish case use:

#include <list>

using namespace std;

template <typename T>
void doSomething(T it); /*Pre-condition: must be passed a dereferencible object.*/

int main(){
    list<int> intList;

    intList.push_back(10);
    intList.push_back(20);
    intList.push_back(10);
    intList.push_back(30);

    list<int>::iterator it;

    for (it = intList.begin(); it != intList.end(); it++){
        if (*it == 10) doSomething(it);
    }; 
}

template <typename T>
void doSomething(T it){
    (*it) = 200;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM