2

I'm trying to implement a sparse 3D grid with std::set container, but I can't understand the error returned from the compiler, this is the minimal example I'm trying to run:

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

and this is the compiler error:

In file included from /usr/include/c++/4.8/string:48:0, from /usr/include/c++/4.8/bits/locale_classes.h:40, from /usr/include/c++/4.8/bits/ios_base.h:41, from /usr/include/c++/4.8/ios:42, from /usr/include/c++/4.8/ostream:38, from /usr/include/c++/4.8/iostream:39, from /home/dede/build/sparse_grid/main.cpp:1: /usr/include/c++/4.8/bits/stl_function.h: In instantiation of 'bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cell]': /usr/include/c++/4.8/bits/stl_tree.h:1324:11: required from 'std::pair std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc = std::allocator; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = Cell]' /usr/include/c++/4.8/bits/stl_tree.h:1377:47: required from 'std::pair, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(_Arg&&) [with _Arg = Cell; _Key = Cell; _Val = Cell; _KeyOfValue = std::_Identity; _Compare = std::less; _Alloc = std::allocator]' /usr/include/c++/4.8/bits/stl_set.h:472:40:
required from 'std::pair, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(std::set<_Key, _Compare, _Alloc>::value_type&&) [with _Key = Cell; _Compare = std::less; _Alloc = std::allocator; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename _Alloc::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator; std::set<_Key, _Compare, _Alloc>::value_type = Cell]' /home/dede/build/sparse_grid/main.cpp:53:57: required from here /usr/include/c++/4.8/bits/stl_function.h:235:20: error: passing 'const Cell' as 'this' argument of 'bool Cell::operator<(const Cell&)' discards qualifiers [-fpermissive] { return __x < __y; } ^ make[2]: * [CMakeFiles/sparse_grid.dir/main.cpp.o] Error 1 make[1]: * [CMakeFiles/sparse_grid.dir/all] Error 2 make: *** [all] Error 2

I would really appreciate if someone could tell me what I'm doing wrong.

Thanks, Federico

3 Answers 3

3

You should declare your boolean operator functions as const members:

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

Otherwise these cannot be used with rvalue objects of Cell.

Sign up to request clarification or add additional context in comments.

Comments

2

You have defined operator < in Cell, but the error says it wants bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cell]. Notice you should make your member function const.

You could provide a non-member function for less, which can use your member function, once the it is const.

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

However, std::less will provide this for you, provided your member function is const.

Comments

0

You have declared your Parameters for > and == operators overloads as const and you are passing a temporary.

Just create a temporary Object of Cell within the loop and insert it in cell

Do it like this :

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

Your compilation should succeed.

4 Comments

"Your compilation should succeed." Huh??
Doesn't have anything to do with the compiler error from the OP.
@πάνταῥεῖ I didnt see you your answer , after your comment if just saw it . :)
@πάνταῥεῖ I think this is Compiler error as Template Instantiation happens at Compile time and this instantiation is failing .Do you have other thoughts Correct me if m wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.