c++ 使用std::set实现稀疏3D格网时出错

iq0todco  于 2023-03-14  发布在  其他
关注(0)|答案(3)|浏览(140)

我尝试用std::set container实现一个稀疏的3D网格,但是我不明白编译器返回的错误,这是我尝试运行的最小示例:

#include <iostream>
#include <vector>
#include <limits>
#include <set>

#include <Eigen/Core>

using namespace std;

class Cell {
public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    Cell(const Eigen::Vector3i idx=Eigen::Vector3i::Zero()):_idx(idx) {
        _center = Eigen::Vector3f::Zero();
        _parent = 0;
        _distance = std::numeric_limits<int>::max();
    }

    inline bool operator < (const Cell& c){
        for (int i=0; i<3; i++){
            if (_idx[i]<c._idx[i])
                return true;
            if (_idx[i]>c._idx[i])
                return false;
        }
        return false;
    }

    inline bool operator == (const Cell& c) { return c._idx == _idx;}

private:
    Eigen::Vector3i _idx;
    Eigen::Vector3f _center;
    vector<Eigen::Vector3f> _points;
    Cell* _parent;
    size_t _closest_point;
    float _distance;
    int _tag;
};

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

    set<Cell> grid;

    float max = 1, min = -1;
    int dim = 5;
    float delta = (max-min)/(dim-1);

    for(int k = 0; k < dim; k++)
        for(int j = 0; j < dim; j++)
            for(int i = 0; i < dim; i++)
                grid.insert(Cell(Eigen::Vector3i(i,j,k)));

    return 0;
}

这是编译器错误:
在以下文件中包含:/usr/include/c++/4.8/字符串:48:0、/usr/include/c++/4.8/位/区域设置类.h:40、/usr/include/c++/4.8/位/ios_base.h:41、/usr/include/c++/4.8/ios:42、/usr/include/c++/4.8/ostream:38、/usr/include/c++/4.8/iostream:39、/home/dede/build/稀疏网格/main.cpp:1:/usr/包含/c++/4.8位/stl_函数.h:在示例化“bool std::less<_Tp>::operator()(const _Tp&,const _Tp&)const [with _Tp =单元格]”时:/usr/包含/c++/4.8/位/stl树.h:1324:11:从“标准::对标准::_Rb树〈_密钥,_值,_值的密钥,_比较,_分配〉::_M_获取_插入_唯一_位置(常量密钥类型&)[带有_密钥=单元格;_瓦尔=单元格;_值的关键字=标准::_标识;_比较=标准::小于;_Alloc =标准::分配器;标准::_Rb树〈_键、_瓦尔、_值键、_比较、_分配〉::键类型=单元格]' /usr/包含/c++/4.8/位/标准树。小时:1377:47:从“标准::对,布尔值〉标准::_Rb树〈_键,_瓦尔,_键类型,_比较,_分配〉::_M_插入_唯一(_Arg&&)[with _Arg =单元格;_Key =单元格;_瓦尔=单元格;_值的关键字=标准::_标识;_比较=标准::小于;_Alloc =标准::分配器]' /usr/包含/c++/4.8/位/标准集。h:472:40:
从“标准::对,_比较,类型名称_分配::重新绑定<_Key>::其他〉::常量迭代器,布尔值〉标准::集〈_键,_比较,_分配〉::插入(标准::集〈_键,_比较,_分配〉::值类型&&)[with _Key =单元格;_比较=标准::小于;_Alloc =标准::分配器;类型名称std::_Rb树〈_密钥,_密钥,std::_标识<_Key>,_比较,类型名称分配::重新绑定<_Key>::其他〉::常量迭代器= std::_Rb树常量迭代器;std::设置〈键、比较、分配〉::值类型=单元格]' /home/dede/build/稀疏网格/main。cpp:53:57:从此处开始需要/usr/include/c++/4.8/bits/stl_function.h:235:20:错误:将'const Cell'作为'bool Cell::operator〈(const Cell&)'的'this'参数传递将丢弃限定符[-fpermissive] { return __x〈__y;} ^制造商[2]:***[CMakeFiles/稀疏网格.目录/主.cpp.o]错误1生成[1]:***[CMakeFiles/稀疏网格.目录/all]错误2生成:***[全部]错误2
如果有人能告诉我哪里做错了我会很感激的。
谢了,费德里科

62o28rlo

62o28rlo1#

您应该将布尔运算符函数声明为const成员:

inline bool operator < (const Cell& c) const {
                                    // ^^^^^
    for (int i=0; i<3; i++){
        if (_idx[i]<c._idx[i])
            return true;
        if (_idx[i]>c._idx[i])
            return false;
    }
    return false;
}

inline bool operator == (const Cell& c) const { return c._idx == _idx;}
                                     // ^^^^^

否则,它们不能用于Cell的右值对象。

5lhxktic

5lhxktic2#

你已经在Cell中定义了operator <,但是错误说它需要bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cell]。注意你应该让你的成员函数为const
您可以为less提供一个非成员函数,一旦它是常量,它就可以使用您的成员函数。

bool operator <(const Cell &a, const Cell &b)
{
    return a < b;
}

但是,std::less将为您提供这一点,* 假设 * 您的成员函数是const

xe55xuns

xe55xuns3#

您已经将〉和==运算符重载的Parameter声明为const,并且正在传递临时变量。
只需在循环中创建一个临时的单元格对象并将其插入单元格
这样做:

for(int k = 0; k < dim; k++)
        for(int j = 0; j < dim; j++)
            for(int i = 0; i < dim; i++)
{
             Eigen::Vector3i(i,j,k) eigenVec;
             Cell  cell(eigenVec);
             grid.insert(cell);
}

编译应该会成功。

相关问题