0

I am transferring something from another language to C++, as a complete beginner to C++ and I am trying to learn some essentials around struct creation and use in maps. I have this sketched below:

struct Cubic {
    int X, Y, Z;
    Cubic Neighbor(int);
};

struct Space{
    Cubic location; 
    bool open;     
    bool blocked;
};

class Table {
    int bound;
    Cubic center;
    std::map<Cubic, Space> grid;
    Table* New(int, Cubic);
};

std::map<Cubic, Space> Allocate(int bound, Cubic center)
{
    std::map<Cubic, Space> ret;
    for (int x = -bound; x <= bound; x++) {
        for (int y = std::max(-bound, -x-bound); y <= std::min(bound, -x+bound); y++) {
            int z = -x - y;
            Cubic cb = CubicAdd(center, {x, y, z});
            ret[cb] = {location: cb, open: true};        //THIS IS A HUGE ERROR, see below
        };
    };
    return ret;
}

It is basically a table cubic coordinates for hexagons. The other code can be posted, but it is not relevant to the matter at hand; i.e. it works in there and I have no problems understanding that, the issue is in trying to get to an understanding of basic C++ coding, which here is a map of Cubic structs keys to Space pointers embedded in a class Table....which I have not even gotten to instantiating yet.

Error:

doing

c++ table.cc -std=c++0x (for 2 files I have table.h & table.cc) generates this:

In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc: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 = Cubic]’:
/usr/include/c++/4.8/bits/stl_map.h:463:31:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Cubic; _Tp = Space; _Compare = std::less<Cubic>; _Alloc = std::allocator<std::pair<const Cubic, Space> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Space; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Cubic]’
table.cc:63:13:   required from here
/usr/include/c++/4.8/bits/stl_function.h:235:20: error: no match for ‘operator<’ (operand types are ‘const Cubic’ and ‘const Cubic’)
{ return __x < __y; }
^
/usr/include/c++/4.8/bits/stl_function.h:235:20: note: candidates are:
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:64:0,
from /usr/include/c++/4.8/bits/stl_tree.h:61,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_pair.h:220:5: note: template<class _T1, class _T2> constexpr bool std::operator<(const std::pair<_T1, _T2>&, const std::pair<_T1, _T2>&)
operator<(const pair<_T1, _T2>& __x, const pair<_T1, _T2>& __y)
^
/usr/include/c++/4.8/bits/stl_pair.h:220:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::pair<_T1, _T2>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/stl_tree.h:61,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:297:5: note: template<class _Iterator> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_Iterator>&)
operator<(const reverse_iterator<_Iterator>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:297:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::reverse_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/stl_tree.h:61,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:347:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::reverse_iterator<_Iterator>&, const std::reverse_iterator<_IteratorR>&)
operator<(const reverse_iterator<_IteratorL>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:347:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::reverse_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/stl_tree.h:61,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:1055:5: note: template<class _IteratorL, class _IteratorR> bool std::operator<(const std::move_iterator<_Iterator>&, const std::move_iterator<_IteratorR>&)
operator<(const move_iterator<_IteratorL>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:1055:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::move_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/bits/stl_algobase.h:67:0,
from /usr/include/c++/4.8/bits/stl_tree.h:61,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_iterator.h:1061:5: note: template<class _Iterator> bool std::operator<(const std::move_iterator<_Iterator>&, const std::move_iterator<_Iterator>&)
operator<(const move_iterator<_Iterator>& __x,
^
/usr/include/c++/4.8/bits/stl_iterator.h:1061:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::move_iterator<_Iterator>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/map:60:0,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_tree.h:917:5: note: template<class _Key, class _Val, class _KeyOfValue, class _Compare, class _Alloc> bool std::operator<(const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&, const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>&)
operator<(const _Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>& __x,
^
/usr/include/c++/4.8/bits/stl_tree.h:917:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/stdexcept:39,
from /usr/include/c++/4.8/array:38,
from /usr/include/c++/4.8/tuple:39,
from /usr/include/c++/4.8/bits/stl_map.h:63,
from /usr/include/c++/4.8/map:61,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2569:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2569:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/stdexcept:39,
from /usr/include/c++/4.8/array:38,
from /usr/include/c++/4.8/tuple:39,
from /usr/include/c++/4.8/bits/stl_map.h:63,
from /usr/include/c++/4.8/map:61,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2581:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const std::basic_string<_CharT, _Traits, _Alloc>&, const _CharT*)
operator<(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2581:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::basic_string<_CharT, _Traits, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/string:52:0,
from /usr/include/c++/4.8/stdexcept:39,
from /usr/include/c++/4.8/array:38,
from /usr/include/c++/4.8/tuple:39,
from /usr/include/c++/4.8/bits/stl_map.h:63,
from /usr/include/c++/4.8/map:61,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/basic_string.h:2593:5: note: template<class _CharT, class _Traits, class _Alloc> bool std::operator<(const _CharT*, const std::basic_string<_CharT, _Traits, _Alloc>&)
operator<(const _CharT* __lhs,
^
/usr/include/c++/4.8/bits/basic_string.h:2593:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   mismatched types ‘const _CharT*’ and ‘Cubic’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/tuple:39:0,
from /usr/include/c++/4.8/bits/stl_map.h:63,
from /usr/include/c++/4.8/map:61,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/array:238:5: note: template<class _Tp, long unsigned int _Nm> bool std::operator<(const std::array<_Tp, _Nm>&, const std::array<_Tp, _Nm>&)
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
^
/usr/include/c++/4.8/array:238:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::array<_Tp, _Nm>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/bits/stl_map.h:63:0,
from /usr/include/c++/4.8/map:61,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/tuple:824:5: note: template<class ... _TElements, class ... _UElements> constexpr bool std::operator<(const std::tuple<_Args1 ...>&, const std::tuple<_Args2 ...>&)
operator<(const tuple<_TElements...>& __t,
^
/usr/include/c++/4.8/tuple:824:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::tuple<_Args1 ...>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/map:61:0,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_map.h:979:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::map<_Key, _Tp, _Compare, _Alloc>&, const std::map<_Key, _Tp, _Compare, _Alloc>&)
operator<(const map<_Key, _Tp, _Compare, _Alloc>& __x,
^
/usr/include/c++/4.8/bits/stl_map.h:979:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::map<_Key, _Tp, _Compare, _Alloc>’
{ return __x < __y; }
^
In file included from /usr/include/c++/4.8/map:62:0,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_multimap.h:881:5: note: template<class _Key, class _Tp, class _Compare, class _Alloc> bool std::operator<(const std::multimap<_Key, _Tp, _Compare, _Alloc>&, const std::multimap<_Key, _Tp, _Compare, _Alloc>&)
operator<(const multimap<_Key, _Tp, _Compare, _Alloc>& __x,
^
/usr/include/c++/4.8/bits/stl_multimap.h:881:5: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/4.8/bits/stl_tree.h:63:0,
from /usr/include/c++/4.8/map:60,
from table.h:3,
from table.cc:1:
/usr/include/c++/4.8/bits/stl_function.h:235:20: note:   ‘const Cubic’ is not derived from ‘const std::multimap<_Key, _Tp, _Compare, _Alloc>’
{ return __x < __y; }
^
blueblank
  • 4,724
  • 9
  • 48
  • 73
  • You have to implement the `operator<` for your Cubic class (that's used as the key template) so that the map can sort the entries. You could also define your own comparator. – aslg Jul 23 '15 at 16:58
  • _"I am transferring something from another language to C++, as a complete beginner to C++"_ Perhaps you are the wrong team member for this task...? – Lightness Races in Orbit Jul 23 '15 at 18:07
  • That is not a productive or helpful attitude,LRO -- I have a team of one: me. And beside, my own personal preferred way to learn is immersion until I can break what I'm learning into understandable chunks. Troll harder, *************. – blueblank Jul 23 '15 at 19:00

2 Answers2

0

std::map<> needs comparison operators to sort and order its data. By default, it uses the < operator. Looking at your errors, it looks like such an operator is not implemented in your Cubic class. You can solve this problem by overloading < in your Cubic class or use a custom comparator.

Heres info for a custom comparator.

Heres info for operator overloading.

Community
  • 1
  • 1
yizzlez
  • 8,757
  • 4
  • 29
  • 44
  • `std::map` does not use `<` by default but `std::less`, which then delegates to `<` for non-pointer types. The difference is usually irrelevant, but `std::less` is necessary to allow pointers as keys; the behaviour would not be guaranteed for `<`. – Christian Hackl Jul 23 '15 at 18:54
  • What is more idiomatic/ considered better -- overloading the operator or providing a custom method? – blueblank Jul 23 '15 at 23:39
0

You didn't post a definition of Cubic, but the issue is from the first error:

/usr/include/c++/4.8/bits/stl_function.h: In instantiation of ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = Cubic]’:
/usr/include/c++/4.8/bits/stl_map.h:463:31:   required from ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = Cubic; _Tp = Space; _Compare = std::less<Cubic>; _Alloc = std::allocator<std::pair<const Cubic, Space> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = Space; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = Cubic]’
table.cc:63:13:   required from here
/usr/include/c++/4.8/bits/stl_function.h:235:20: error: no match for ‘operator<’ (operand types are ‘const Cubic’ and ‘const Cubic’)
{ return __x < __y; }
^

std::map is a binary tree (red-black tree specifically) and it needs its keys to be LessThanComparable. By default, this uses operator< and your Key (Cubic) does not have a member or non-member operator< defined. The rest of the compile error is the compiler trying to stick Cubic into all the other operator<'s that it can find for any other type - none of which apply since Cubic isn't convertible to any of those.

So either provide one:

bool operator<(const Cubic& a, const Cubic& b) {
    // something reasonable, probably like
    return std::tie(a.X, a.Y, a.Z) < std::tie(b.X, b.Y, b.Z);
}

Or provide your map with a custom comparator:

struct CubicCompare {
    bool operator()(const Cubic& a, const Cubic& b) const {
        // something reasonable, return true if a is "less than" b
    }
};

std::map<Cubic, Space, CubicCompare> ret;
Barry
  • 286,269
  • 29
  • 621
  • 977
  • Cubic definition is added. – blueblank Jul 23 '15 at 17:10
  • I do not think that `std::map` is required to be a red-black tree. – Slava Jul 23 '15 at 17:12
  • 2 other methods should be mentioned probably - specialization for `std::less` and `operator<` as a method of class `Cubic` – Slava Jul 23 '15 at 17:15
  • @blueblank Right, so it doesn't have `operator<` defined. I added an example for what it might look like. – Barry Jul 23 '15 at 17:15
  • ‘tie’ is not a member of ‘std’ for the first, the second does work though, which is preferable and/or idiotmatic? – blueblank Jul 23 '15 at 20:38
  • @blueblank Did you include [``](http://en.cppreference.com/w/cpp/utility/tuple/tie)? It depends on whether you want to compare your `Cubic`s outside of your map - doesn't matter. – Barry Jul 23 '15 at 20:44