unordered_map 中的用户自定义哈希函数时无法解码 g++ 中模糊的编译器错误
Cannot decode an obscured compiler error in g++ when user custom hash function in unordered_map
这是我要编译的代码:
#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 Studio 2015 上编译良好(有一些不相关的警告),但它在 g++ 上惨败(如在 ideone 上:https://ideone.com/d1Rs1I)
编译器输出如下:
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++)
^
编译器错误输出看起来与此线程上发布的非常相似。
但我确定我的散列函数是常量。不知道为什么它仍然抱怨我的哈希函数不是 const。
您使用的迭代器类型不正确。
你有:
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
。如果你像这样将它添加到你的代码中:
struct SlantedLine
{
public:
int slope_numerator;
int slope_denominator;
int intercept_numerator;
int intercept_denominator;
void operator()(const SlantedLine&) const
{
}
};
编译通过。它确实要求这个运算符,因为它认为 SlantedLine
是哈希类型。
这是我要编译的代码:
#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 Studio 2015 上编译良好(有一些不相关的警告),但它在 g++ 上惨败(如在 ideone 上:https://ideone.com/d1Rs1I)
编译器输出如下:
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++)
^
编译器错误输出看起来与此线程上发布的非常相似。
但我确定我的散列函数是常量。不知道为什么它仍然抱怨我的哈希函数不是 const。
您使用的迭代器类型不正确。
你有:
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
。如果你像这样将它添加到你的代码中:
struct SlantedLine
{
public:
int slope_numerator;
int slope_denominator;
int intercept_numerator;
int intercept_denominator;
void operator()(const SlantedLine&) const
{
}
};
编译通过。它确实要求这个运算符,因为它认为 SlantedLine
是哈希类型。