首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当用户在g++中自定义哈希函数时,无法解码unordered_map中模糊的编译器错误

当用户在g++中自定义哈希函数时,无法解码unordered_map中模糊的编译器错误
EN

Stack Overflow用户
提问于 2016-03-17 04:07:34
回答 1查看 1.6K关注 0票数 3

下面是我要编译的代码:

代码语言:javascript
运行
复制
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <vector>
#include <string>

using namespace std;

namespace _LEET_MAX_POINTS_ON_A_LINE
{
    struct Point
    {
        int x;
        int y;
        Point() : x(0), y(0) {}
        Point(int a, int b) : x(a), y(b) {}
    };

    struct SlantedLine
    {
    public:
        int slope_numerator;
        int slope_denominator;
        int intercept_numerator;
        int intercept_denominator;
    };

    struct SlantedLineHash
    {
        size_t operator()(const SlantedLine& k) const
        {
            return k.slope_numerator ^ k.slope_denominator ^ k.intercept_numerator ^ k.intercept_denominator;
        }
    };

    struct SlantedLineEqual
    {
        size_t operator()(const SlantedLine& line1, const SlantedLine& line2) const
        {
            return (line1.slope_numerator == line2.slope_numerator) && (line1.slope_denominator == line2.slope_denominator) && (line1.intercept_numerator == line2.intercept_numerator) && (line1.intercept_denominator == line2.intercept_denominator);
        }
    };

    class Solution
    {
    public:
        int maxPoints(vector<Point>& points)
        {
            if (points.size() == 0)
            {
                return 0;
            }

            unordered_map<SlantedLine, unordered_set<int>, SlantedLineHash, SlantedLineEqual> slantedLineToPointsMap;
            unordered_map<int, unordered_set<int>> verticalLineToPointsMap;
            for (size_t i = 0; i < points.size(); i++)
            {
                for (size_t j = i + 1; j < points.size(); j++)
                {
                    int x1 = points[i].x;
                    int y1 = points[i].y;
                    int x2 = points[j].x;
                    int y2 = points[j].y;

                    if (x1 == x2)
                    {
                        unordered_map<int, unordered_set<int>>::iterator probe = verticalLineToPointsMap.find(x1);
                        if (probe == verticalLineToPointsMap.end())
                        {
                            unordered_set<int> points;
                            points.insert(i);
                            points.insert(j);
                            verticalLineToPointsMap.insert(pair<int, unordered_set<int>>(x1, points));
                        }
                        else
                        {
                            probe->second.insert(i);
                            probe->second.insert(j);
                        }
                    }
                    else
                    {
                        int slope_numerator = y2 - y1;
                        int slope_denominator = x2 - x1;
                        int intercept_numerator = y1 * x2 - x1 * y2;
                        int intercept_denominator = x2 - x1;
                        simplify_fraction(&slope_numerator, &slope_denominator);
                        simplify_fraction(&intercept_numerator, &intercept_denominator);
                        SlantedLine line;
                        line.slope_numerator = slope_numerator;
                        line.slope_denominator = slope_denominator;
                        line.intercept_numerator = intercept_numerator;
                        line.intercept_denominator = intercept_denominator;
                        unordered_map<SlantedLine, unordered_set<int>, SlantedLine, SlantedLineEqual>::iterator probe = slantedLineToPointsMap.find(line);
                        if (probe == slantedLineToPointsMap.end())
                        {
                            unordered_set<int> points;
                            points.insert(i);
                            points.insert(j);
                            slantedLineToPointsMap.insert(pair<SlantedLine, unordered_set<int>>(line, points));
                        }
                        else
                        {
                            probe->second.insert(i);
                            probe->second.insert(j);
                        }
                    }
                }
            }

            size_t maxPoints = 0;
            for (unordered_map<int, unordered_set<int>>::iterator i = verticalLineToPointsMap.begin(); i != verticalLineToPointsMap.end(); i++)
            {
                maxPoints = max(maxPoints, i->second.size());
            }
            for (unordered_map<SlantedLine, unordered_set<int>, SlantedLine, SlantedLineEqual>::iterator i = slantedLineToPointsMap.begin(); i != slantedLineToPointsMap.end(); i++)
            {
                maxPoints = max(maxPoints, i->second.size());
            }

            return maxPoints;
        }
    private:
        void simplify_fraction(int* numerator, int* denominator)
        {
            int common_factor = gcd(*numerator, *denominator);
            *numerator /= common_factor;
            *denominator /= common_factor;
            if (*denominator < 0)
            {
                *numerator *= -1;
                *denominator *= -1;
            }
        }

        int gcd(int a, int b)
        {
            if (a < 0)
            {
                return gcd(-a, b);
            }
            else if (b < 0)
            {
                return gcd(a, -b);
            }
            else if (b > a)
            {
                return gcd(b, a);
            }
            else
            {
                if (b == 0)
                {
                    return a;
                }
                else
                {
                    return gcd(b, a % b);
                }
            }
        }
    };
};

using namespace _LEET_MAX_POINTS_ON_A_LINE;

int LEET_MAX_POINTS_ON_A_LINE()
{
    Solution solution;
    return 0;
}

代码在Visual 2015上编译得很好(不相关的几个警告),但在g++上(如ideone:https://ideone.com/d1Rs1I)却不幸地失败了。

下面是编译器的输出:

代码语言:javascript
运行
复制
In file included from /usr/include/c++/5/bits/hashtable.h:35:0,
                 from /usr/include/c++/5/unordered_map:47,
                 from prog.cpp:1:
/usr/include/c++/5/bits/hashtable_policy.h: In instantiation of 'struct std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine>':
/usr/include/c++/5/type_traits:137:12:   required from 'struct std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> >'
/usr/include/c++/5/type_traits:148:38:   required from 'struct std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
/usr/include/c++/5/bits/unordered_map.h:100:66:   required from 'class std::unordered_map<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, std::unordered_set<int>, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLineEqual>'
prog.cpp:96:102:   required from here
/usr/include/c++/5/bits/hashtable_policy.h:85:34: error: no match for call to '(const _LEET_MAX_POINTS_ON_A_LINE::SlantedLine) (const _LEET_MAX_POINTS_ON_A_LINE::SlantedLine&)'
  noexcept(declval<const _Hash&>()(declval<const _Key&>()))>
                                  ^
In file included from /usr/include/c++/5/bits/move.h:57:0,
                 from /usr/include/c++/5/bits/stl_pair.h:59,
                 from /usr/include/c++/5/utility:70,
                 from /usr/include/c++/5/unordered_map:38,
                 from prog.cpp:1:
/usr/include/c++/5/type_traits: In instantiation of 'struct std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >':
/usr/include/c++/5/bits/unordered_map.h:100:66:   required from 'class std::unordered_map<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, std::unordered_set<int>, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLineEqual>'
prog.cpp:96:102:   required from here
/usr/include/c++/5/type_traits:148:38: error: 'value' is not a member of 'std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> >'
     : public integral_constant<bool, !_Pp::value>
                                      ^
In file included from /usr/include/c++/5/unordered_map:48:0,
                 from prog.cpp:1:
/usr/include/c++/5/bits/unordered_map.h: In instantiation of 'class std::unordered_map<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, std::unordered_set<int>, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLineEqual>':
prog.cpp:96:102:   required from here
/usr/include/c++/5/bits/unordered_map.h:100:66: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef __umap_hashtable<_Key, _Tp, _Hash, _Pred, _Alloc>  _Hashtable;
                                                                  ^
/usr/include/c++/5/bits/unordered_map.h:107:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::key_type key_type;
                                             ^
/usr/include/c++/5/bits/unordered_map.h:108:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::value_type value_type;
                                               ^
/usr/include/c++/5/bits/unordered_map.h:109:48: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::mapped_type mapped_type;
                                                ^
/usr/include/c++/5/bits/unordered_map.h:110:43: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::hasher hasher;
                                           ^
/usr/include/c++/5/bits/unordered_map.h:111:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::key_equal key_equal;
                                              ^
/usr/include/c++/5/bits/unordered_map.h:112:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::allocator_type allocator_type;
                                                   ^
/usr/include/c++/5/bits/unordered_map.h:117:45: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::pointer  pointer;
                                             ^
/usr/include/c++/5/bits/unordered_map.h:118:50: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::const_pointer const_pointer;
                                                  ^
/usr/include/c++/5/bits/unordered_map.h:119:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::reference  reference;
                                               ^
/usr/include/c++/5/bits/unordered_map.h:120:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::const_reference const_reference;
                                                    ^
/usr/include/c++/5/bits/unordered_map.h:121:46: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::iterator  iterator;
                                              ^
/usr/include/c++/5/bits/unordered_map.h:122:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::const_iterator const_iterator;
                                                   ^
/usr/include/c++/5/bits/unordered_map.h:123:51: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::local_iterator local_iterator;
                                                   ^
/usr/include/c++/5/bits/unordered_map.h:124:57: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::const_local_iterator const_local_iterator;
                                                         ^
/usr/include/c++/5/bits/unordered_map.h:125:47: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::size_type  size_type;
                                               ^
/usr/include/c++/5/bits/unordered_map.h:126:52: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       typedef typename _Hashtable::difference_type difference_type;
                                                    ^
/usr/include/c++/5/bits/unordered_map.h:280:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       operator=(initializer_list<value_type> __l)
       ^
/usr/include/c++/5/bits/unordered_map.h:379:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
  emplace(_Args&&... __args)
  ^
/usr/include/c++/5/bits/unordered_map.h:432:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       insert(const value_type& __x)
       ^
/usr/include/c++/5/bits/unordered_map.h:439:2: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
  insert(_Pair&& __x)
  ^
/usr/include/c++/5/bits/unordered_map.h:499:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       insert(initializer_list<value_type> __l)
       ^
/usr/include/c++/5/bits/unordered_map.h:645:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       equal_range(const key_type& __x)
       ^
/usr/include/c++/5/bits/unordered_map.h:649:7: error: 'value' is not a member of 'std::__not_<std::__and_<std::__is_fast_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine>, std::__detail::__is_noexcept_hash<_LEET_MAX_POINTS_ON_A_LINE::SlantedLine, _LEET_MAX_POINTS_ON_A_LINE::SlantedLine> > >'
       equal_range(const key_type& __x) const
       ^
prog.cpp: In member function 'int _LEET_MAX_POINTS_ON_A_LINE::Solution::maxPoints(std::vector<_LEET_MAX_POINTS_ON_A_LINE::Point>&)':
prog.cpp:97:29: error: 'probe' was not declared in this scope
                         if (probe == slantedLineToPointsMap.end())
                             ^
prog.cpp:118:142: error: 'i' was not declared in this scope
             for (unordered_map<SlantedLine, unordered_set<int>, SlantedLine, SlantedLineEqual>::iterator i = slantedLineToPointsMap.begin(); i != slantedLineToPointsMap.end(); i++)
                                                                                                                                          ^

编译器错误输出非常类似于发布在这个线程上的输出。

map with an std::pair as key

但我确信我的散列函数是const。不知道它为什么还在抱怨,我的散列函数不是const。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-17 08:10:10

您使用的迭代器类型不正确。

你有:

代码语言:javascript
运行
复制
unordered_map<SlantedLine, unordered_set<int>, SlantedLineHash, SlantedLineEqual> slantedLineToPointsMap;
...
unordered_map<SlantedLine, unordered_set<int>, SlantedLine, SlantedLineEqual>::iterator probe = slantedLineToPointsMap.find(line);
...
for (unordered_map<SlantedLine, unordered_set<int>, SlantedLine, SlantedLineEqual>::iterator i = slantedLineToPointsMap.begin(); i != slantedLineToPointsMap.end(); i++)

您可以看到,您指定了错误的迭代器类型--要么将类型更改为auto (这将有助于避免此类问题),要么使用unordered_map<SlantedLine, unordered_set<int>, SlantedLineHash, SlantedLineEqual>::iterator

最初的错误并没有那么可怕-它告诉您编译器需要void SlantedLine::operator()(const SlantedLine&) const。如果将它添加到代码中,如下所示:

代码语言:javascript
运行
复制
struct SlantedLine
{
public:
    int slope_numerator;
    int slope_denominator;
    int intercept_numerator;
    int intercept_denominator;

    void operator()(const SlantedLine&) const
    {

    }
};

它会编译。它确实要求这个操作符,因为它认为SlantedLine是哈希类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36051496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档