c++ - 定义运算符重载时删除 vector 的对象元素时出错

标签 c++ vector compiler-bug

在下面的简单示例程序中,我有一个对象 vector t_cell我用 5 个元素初始化。我还有一个整数测试 vector 。

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

class t_cell {
    public:
        int id;

    t_cell operator = ( const t_cell &rhs_cell ){
        t_cell lhs_cell;
        lhs_cell.id = rhs_cell.id;
        return lhs_cell;
    }
};


int main(){

    std::vector<int   > test ( 5 );
    std::vector<t_cell> cells( 5 );

    for( size_t icell=0; icell < cells.size(); icell++ ){
        test [icell]    = icell;
        cells[icell].id = icell;
    }

    for( size_t icell=0; icell < cells.size(); icell++ ){
        cout << "before =" << icell << test [icell] << cells[icell].id << endl;
    }
    cout << endl;

    // Erase
    cells.erase( cells.begin() + 3 );
    test .erase( test .begin() + 3 );

    for( size_t icell=0; icell < cells.size(); icell++ ){
        cout << "after  =" << icell << cells[icell].id << test [icell] << endl;
    }

    return 0;
}
删除元素适用于整数 vector ,但不适用于对象 vector :
before =000
before =111
before =222
before =333
before =444

after  =000
after  =111
after  =222
after  =334
循环索引表明 vector 的大小已减小(现在仅从 0 减少到 3)。然而,id第 3 个元素的 未正确删除。
我发现问题来自运算符重载定义。删除按预期工作:
before =000
before =111
before =222
before =333
before =444

after  =000
after  =111
after  =222
after  =344
GCC 8.3.1 和 10.1.0 产生相同的行为。我编译了没有标志的代码。

最佳答案

operator=的目的是要改*this匹配操作数的状态,然后返回对 *this 的引用,但这不是您正在做的 - 相反,您正在创建一个新值并返回它。调用者会立即丢弃返回值,因此调用运算符不会对程序状态产生任何可观察到的影响。
将您的代码更改为变异 *this并返回对自身的引用:

t_cell & operator = ( const t_cell &rhs_cell ){
    id = rhs_cell.id;
    return *this;
}
当然,在这种情况下,您的类是隐式可复制的,因为所有成员都是可复制的。您可以简单地不定义 operator=并且编译器会为你生成一个合适的,它会做与我上面展示的操作符完全相同的事情。

关于c++ - 定义运算符重载时删除 vector 的对象元素时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63063047/

相关文章:

c++ - 我是否需要在单语言 UWP 应用程序中使用 create_async?

C++ 无法填充数据

c++ - std::thread 消耗 Qt 中的所有 CPU

C++ vector<char> 和套接字

c++ - 如何调整 std::vector<std::queue<std::unique_ptr<int>>> 的大小?

c++ - 使用 VS2010 SP1 的函数模板中的编译器错误

c++ - 为什么我得到 E_OUTOFMEMORY?

r - 根据另一个向量的向量元素的索引

c++ - 如何快速从已排序的 vector 中获取已排序的子 vector

c++ - 一元 - 和 n - 之间有区别吗