简体   繁体   中英

no match for ‘operator=’ using iterator for a vector

I'm developing a Timer class which uses a general tree to store different proccess timings. This struct has string and double variables to store a tag and the time this "tag" expended (every tag corresponds to some real procces). Here is the definition:

struct TimerNode
{
    double time_value;
    std::string name;
    std::vector<TimerNode*> children;

    TimerNode(){};
    TimerNode(const std::string name): name(name){}
    TimerNode& operator=(const TimerNode& other){//CopyAssignable
        this->time_value=other.time_value; this->name=other.name;
        return *this;}
    TimerNode(const TimerNode& other){//CopyConstructible 
        this->time_value=other.time_value; this->name=other.name;}
}tree_;

This struct is inside the timer class that will use it to maintain a record of the time used by each proccess. It has also a function called open_register that will be called each time the timer is called and receives a string with the tag name the user decided (to tag different proccesses). Then, this function will check is this tag has been used before in order to sum up the time to the previous used time by that proccess. So, it must check every child the struct could have to check it, and I use an iterator because I will search inside std::vector children. So

TimerNode* actual_timer = &open_timers_.back();   //open_timers is a stack
std::vector<TimerNode>::iterator it;

for(*it=actual_timer->children.begin(); it != actual_timer->children.end(); ++it){
    if(it->name == received_name){//we found it.
        /*At this point we need to put the node associated with this
        * into the stack and start counting because it is a child
        * that was used before but stopped. So we will add the time
        * expended this time to the value it already has.*/
        open_timers_.push_back(*it);
        break;
    }
}

However when compiling g++ complains in the for line saying that

../src/include/timer.h:73:46: error: no match for 'operator=' in 'it.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* with _Iterator = const opice::Global_Timer::TimerNode*, _Container = std::vector, __gnu_cxx::__normal_iterator<_Iterator, _Container>::reference = const opice::Global_Timer::TimerNode& = actual_timer->opice::Global_Timer::TimerNode::children.std::vector<_Tp, _Alloc>::begin with _Tp = opice::Global_Timer::TimerNode*, _Alloc = std::allocator, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = opice::Global_Timer::TimerNode**'

I have been looking for solutions and I found some of them like this which seems almost the same problem I have, but it didn't solve it because I had the very same error.

I also saw some other questions related with matching operators but they seems not very similar to my problem. Could you point me out where I make the mistake or what I missed in here? I guess it something related with overloading operator but I can not figure out how to overload the = operator in my struct in order to fix the problem with a vector iterator. Thank you very much.

Remove the asterisk:

for(it=actual_timer->children.begin(); it != actual_timer->children.end(); ++it) {

*it = actual_timer->children.begin() tries to assign actual_timer->children.begin() to the element pointed to by it . Element pointed to by it is not an iterator itself and thus the compilation error. Moreover it is not initialized at that time so accessing the element it points will invoke undefined behavior even if compilation did succeed.

the problem is in your for statement, where you write

*it=actual_timer->children.begin()

instead of

it=actual_timer->children.begin()

you are getting a compilation error because *it means "dereference the iterator named it ", which gives you a reference to TimerNode . Since, hopefully, no TimerNode::operator=(const std::vector<TimerNode>::iterator&) is defined, you get the error.

Also, you are dereferencing a noninitialized pointer, so that if you would have written *it = SomeTimerNode you would have had no compilation error, but you would have been thrown in the undefined behaviour land.

You misplaced the dereference operator in front of it ; to assign to iterator, simply use its variable, not an element it points to.

vector<int> v { 1, 2, 3 };

auto it = v.begin(); 
cout << *it; // prints 1

it = v.begin() + 1;
cout << *it; // prints 2;

*it = 3;
cout << *it; // prints 3; v contains [1,3,3] now

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