【问题标题】:no match for ‘operator=’ using iterator for a vector使用迭代器的向量不匹配'operator ='
【发布时间】:2013-12-27 18:45:00
【问题描述】:

我正在开发一个 Timer 类,它使用通用树来存储不同的进程计时。这个结构有字符串和双变量来存储标签和这个“标签”花费的时间(每个标签对应于一些真实的过程)。这是定义:

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_;

这个结构在计时器类中,它将使用它来维护每个进程使用的时间记录。它还有一个名为 open_register 的函数,每次调用计时器时都会调用该函数,并接收带有用户决定的标签名称的字符串(以标记不同的进程)。然后,这个函数会检查这个标签是否已经被使用过,以便将时间总结为该进程之前使用的时间。因此,它必须检查结构可能必须检查的每个子节点,并且我使用迭代器,因为我将在 std::vector 子节点中进行搜索。所以

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;
    }
}

但是,当编译 g++ 时,在 for 行中抱怨说

../src/include/timer.h:73:46: 错误:'it.__gnu_cxx::__normal_iterator<_iterator _container>::operator* 中的 'operator=' 与 _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>::开始于 _Tp = opice::Global_Timer::TimerNode*, _Alloc = std::allocator, std::vector<_tp _alloc>::iterator = __gnu_cxx::__normal_iterator >,类型名 std::_Vector_base<_tp _alloc>::_Tp_alloc_type::pointer = opice::Global_Timer::TimerNode**'

我一直在寻找解决方案,我发现其中一些像 this 这似乎与我遇到的问题几乎相同,但它没有解决它,因为我遇到了同样的错误。

我还看到了一些与匹配运算符相关的其他问题,但它们似乎与我的问题不太相似。你能指出我在哪里犯了错误或我在这里错过了什么吗?我猜这与重载运算符有关,但我不知道如何在我的结构中重载 = 运算符以解决向量迭代器的问题。非常感谢。

【问题讨论】:

  • 顺便说一句,我想知道的不仅仅是一个解决方案,一个解释这个错误发生的原因。谢谢!
  • 应该是 it=actual_timer->children.begin() (没有尾随 *)。这是因为*它会尝试将 ....begin() 分配给迭代器指向的变量。

标签: c++ vector stl operator-overloading


【解决方案1】:

问题出在你写的for 语句中

*it=actual_timer->children.begin()

而不是

it=actual_timer->children.begin()

您收到编译错误,因为*it 的意思是“取消引用名为it 的迭代器”,它为您提供了对TimerNode 的引用。由于希望没有定义 TimerNode::operator=(const std::vector&lt;TimerNode&gt;::iterator&amp;),因此您会收到错误消息。

此外,您正在取消引用一个未初始化的指针,因此如果您编写 *it = SomeTimerNode,您将不会遇到编译错误,但您会被抛出未定义的行为领域。

【讨论】:

    【解决方案2】:

    去掉星号:

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

    *it = actual_timer-&gt;children.begin() 尝试将actual_timer-&gt;children.begin() 分配给it 指向的元素。 it 指向的元素本身不是迭代器,因此会出现编译错误。此外,it 当时没有初始化,因此即使编译成功,访问它指向的元素也会调用未定义的行为。

    【讨论】:

    • 感谢您快速且易于理解的回答。现在它会抛出其他错误,但与此无关:)
    【解决方案3】:

    你在it前面放错了取消引用操作符;要分配给迭代器,只需使用它的变量,而不是它指向的元素。

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-29
      • 2017-02-28
      • 2017-09-02
      • 2015-02-11
      • 2015-09-09
      相关资源
      最近更新 更多