2

I am using unordered map for the first time and that with custom objects. I tried to write the below functions. There are errors that I need help with.

This is the class.

class Node
{
  public:
    int g= 0, h=0;
    char val;                                                              //Char value in the grid
    pair<int,int> pos,parent;  
    bool par_prsnt = false;                                                //Bool to check if the parent is set


    Node(pair<int,int>nodePos,char value)
    {
    pos=nodePos;
    val=value;
    }  

    int move_cost(Node other)
    {
    if (val=='.')
        return 0;
    else
        return 1;
    }

    pair<int,int> get_pos() const
    {
    return pos;
    }

    void set_parent(pair<int,int> par)
    {
    parent = par;
    par_prsnt = true;
    }

};

Below is the custom functions:

// Custom Hasher for Class Node, to be used for Unordered_set
struct NodeHasher
{
  template <typename T, typename U>
  size_t
  const operator()(const Node &obj)
  {
    pair<T,U> position;
    position = obj.get_pos();
    return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
  }
};

// Custom Comparator for Class Node, to be used for Unordered_set
struct NodeComparator
{
  bool
  const operator()(const Node  &obj1, const  Node  &obj2) const
  {
    if (obj1.get_pos() == obj2.get_pos())
      return true;
    return false;
  }
};

I get the following errors:

Player 1: compilation error
In file included from /usr/include/c++/7/bits/hashtable.h:35:0,
from /usr/include/c++/7/unordered_map:47,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:117,
solution.cc:7:
/usr/include/c++/7/bits/hashtable_policy.h: In instantiation of ‘struct std::__detail::__is_noexcept_hash’:
/usr/include/c++/7/type_traits:143:12: required from ‘struct std::__and_,  std::__detail::__is_noexcept_hash >’
/usr/include/c++/7/type_traits:154:31: required from ‘struct std::__not_, std::__detail::__is_noexcept_hash > >’
/usr/include/c++/7/bits/unordered_set.h:98:63: required from ‘class std::unordered_set’
solution.cc:119:51: required from here
/usr/include/c++/7/bits/hashtable_policy.h:87:34: error: no match for call to ‘(const NodeHasher) (const Node&)’
noexcept(declval()(declval()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
solution.cc:83:9: note: candidate: template const size_t NodeHasher::operator()(const Node&)
const operator()(const Node &obj)
^~~~~~~~
solution.cc:83:9: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/hashtable.h:35:0,
from /usr/include/c++/7/unordered_map:47,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:117,
solution.cc:7:
/usr/include/c++/7/bits/hashtable_policy.h:87:34: note: couldn't deduce template parameter ‘T’
noexcept(declval()(declval()))>
~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/move.h:54:0,
from /usr/include/c++/7/bits/stl_pair.h:59,
from /usr/include/c++/7/bits/stl_algobase.h:64,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/type_traits: In instantiation of ‘struct std::__not_, std::__detail::__is_noexcept_hash > >’:
/usr/include/c++/7/bits/unordered_set.h:98:63: required from ‘class std::unordered_set’
solution.cc:119:51: required from here
/usr/include/c++/7/type_traits:154:31: error: ‘value’ is not a member of ‘std::__and_, std::__detail::__is_noexcept_hash >’
: public __bool_constant
^~~~~~~~~~~~~~~~
In file included from /usr/include/c++/7/unordered_set:48:0,
from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:118,
solution.cc:7:
/usr/include/c++/7/bits/unordered_set.h: In instantiation of ‘class std::unordered_set’:
solution.cc:119:51: required from here
/usr/include/c++/7/bits/unordered_set.h:98:63: error: ‘value’ is not a member of ‘std::__not_, std::__detail::__is_noexcept_hash > >’
typedef __uset_hashtable _Hashtable;
^~~~~~~~~~
/usr/include/c++/7/bits/unordered_set.h:105:45: error: ‘value’ is not a member of ‘std::__not_, std::__detail::__is_noexcept_hash > >’
typedef typename _Hashtable::key_type key_type;
^~~~~~~~ 

The error list is much longer, I think this much maybe enough for someone to understand the error. I referred this page for the custom functions : http://thispointer.com/how-to-use-unordered_set-with-user-defined-classes-tutorial-example/. Any suggestions? Thanks for reading.

Edit 1: Unordered_set creation:

unordered_set<Node,NodeHasher,NodeComparator> openList;

Edit 2: Error in comparison operator.

Player 1: compilation error
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h: In instantiation of ‘bool __gnu_cxx::__ops::_Iter_equals_val::operator()(_Iterator) [with _Iterator = __gnu_cxx::__normal_iterator >; _Value = const Node]’:
/usr/include/c++/7/bits/stl_algo.h:120:14: required from ‘_RandomAccessIterator std::__find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate, std::random_access_iterator_tag) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val]’
/usr/include/c++/7/bits/stl_algo.h:161:23: required from ‘_Iterator std::__find_if(_Iterator, _Iterator, _Predicate) [with _Iterator = __gnu_cxx::__normal_iterator >; _Predicate = __gnu_cxx::__ops::_Iter_equals_val]’
/usr/include/c++/7/bits/stl_algo.h:3907:28: required from ‘_IIter std::find(_IIter, _IIter, const _Tp&) [with _IIter = __gnu_cxx::__normal_iterator >; _Tp = Node]’
solution.cc:147:73: required from here
/usr/include/c++/7/bits/predefined_ops.h:241:17: error: no match for ‘operator==’ (operand types are ‘Node’ and ‘const Node’)
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/stl_iterator.h:859:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator&, const __gnu_cxx::__normal_iterator&)
operator==(const __normal_iterator& __lhs,
^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:859:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::__normal_iterator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/c++/7/bits/stl_algobase.h:67:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/stl_iterator.h:866:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::__normal_iterator&, const __gnu_cxx::__normal_iterator&)
operator==(const __normal_iterator& __lhs,
^~~~~~~~
/usr/include/c++/7/bits/stl_iterator.h:866:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::__normal_iterator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/vector:61,
solution.cc:3:
/usr/include/c++/7/ext/new_allocator.h:155:5: note: candidate: template bool __gnu_cxx::operator==(const __gnu_cxx::new_allocator&, const __gnu_cxx::new_allocator&)
operator==(const new_allocator&, const new_allocator&)
^~~~~~~~
/usr/include/c++/7/ext/new_allocator.h:155:5: note: template argument deduction/substitution failed:
In file included from /usr/include/c++/7/bits/stl_algobase.h:71:0,
from /usr/include/c++/7/vector:60,
solution.cc:3:
/usr/include/c++/7/bits/predefined_ops.h:241:17: note: ‘Node’ is not derived from ‘const __gnu_cxx::new_allocator’
{ return *__it == _M_value; }
~~~~~~^~~~~~~~~~~
solution.cc: In function ‘std::vector aStar(std::vector >&, std::pair, std::pair)’:
solution.cc:173:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
cc1plus: some warnings being treated as errors

1 Answers1

1
struct NodeHasher
{
  template <typename T, typename U>
  size_t const operator()(const Node &obj)
  {
    pair<T,U> position;
    position = obj.get_pos();
    return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
  }
};

The compiler can deduce what T and U are in this case. One solution would be to remove the template and hard code int since you know you are working with a pair of int.

And I believe you misplaced the const specifier -- it should be placed at the end of the declaration

Alternatively, if you want to make NodeHasher work for different types of pair, You can make it a template class instead.

template <typename T, typename U>
struct NodeHasher
{
    size_t operator()(const Node &obj) const
    {
        pair<T, U> position = obj.get_pos();
        return 3* std::hash<T>()(position.first) + std::hash<U>()(position.second) ;
    }
};

And create your unordered_set as

unordered_set<Node, NodeHasher<int,int>, NodeComparator> us; //T and U are int
gchen
  • 1,173
  • 1
  • 7
  • 12
  • this pretty much solved all the value errors, thanks, placed "const" properly and hardcoded "int". However still have some errors in comparison operator for operator() of the hasher function. adding in the edit. – Nothing_8484 Apr 29 '18 at 21:18
  • Have you seen this demo -- https://ideone.com/Vswtlz -- it compiles without any errors, and the only thing that I changed was the NanoHasher part. Perhaps, You have other codes in main? – gchen Apr 29 '18 at 21:26
  • Right that error is not at the hasher function. its the other code. – Nothing_8484 Apr 29 '18 at 21:31