我知道我始终可以使用 set(comp) 构造函数来初始化 set 的比较函数。
但我通常更喜欢重载运算符<。
所以当我想使用位集作为设置键时,我使用下面的代码。
#include <bitset>
#include <set>
using namespace std;
bool operator<(const std::bitset<128>& x, const std::bitset<128>& y)
{
return false;//show the brief idea of overloading operator< ,never mind .
};
int main()
{
set<bitset<128> > s{ bitset<128>() };
return 0;
}
编译器给了我下面这些编译错误。
Error 1 error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 2 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 3 error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 4 error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 5 error C2784: 'bool std::operator <(const std::move_iterator<_RanIt> &,const std::move_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::move_iterator<_RanIt> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 6 error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 7 error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 8 error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'const std::bitset<128>' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
Error 9 error C2676: binary '<' : 'const std::bitset<128>' does not define this operator or a conversion to a type acceptable to the predefined operator c:\program files (x86)\microsoft visual studio 12.0\vc\include\xstddef 193 1 test
但是这段代码可以编译。
#include <bitset>
#include <set>
using namespace std;
struct wrapper
{
std::bitset<128> a;
};
bool operator<(const std::bitset<128>& x, const std::bitset<128>& y)
{
return false;
};
bool operator<(const wrapper& x, const wrapper& y)
{
return x.a<y.a;
};
int main()
{
set<wrapper> s{ wrapper() };
return 0;
}
我想知道为什么。
最佳答案
这与 C++ 中名称查找的复杂性密切相关。
默认情况下,std::set
使用std::less<Key>
作为其比较器,其实现大致如下所示:
template <class K>
struct less {
bool operator()(K const& lhs, K const& rhs) const {
return lhs < rhs; // (*)
}
};
标记的行是 <
的位置实际上被称为。查找哪个<
要调用,我们查看模板定义的范围(不会找到您的 operator<
),然后查看参数的关联命名空间(即 std::
,并且您的 operator<
不在该命名空间中。将其添加到该 namespace 实际上也是非法的)。由于这些查找都找不到任何内容,因此代码格式不正确。
您的第二个示例修复了查找的参数相关部分:现在有一个 operator<
在参数的关联命名空间( ::
)中,它将被找到。
请注意,您仍然拥有 std::set
的std::bitset<N>
。您只需为类模板提供自定义比较器即可。
关于C++ 编译器无法使用我的重载 < 运算符进行位集键比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39135548/