C++ 编译器无法使用我的重载 < 运算符进行位集键比较

标签 c++ overloading grammar

我知道我始终可以使用 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::setstd::bitset<N> 。您只需为类模板提供自定义比较器即可。

关于C++ 编译器无法使用我的重载 < 运算符进行位集键比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39135548/

相关文章:

grammar - 如何改变语法对象中的捕获?

c++ - 这种并发快速排序的实现是否正确?

c++ - 运算符重载 operator= 使用友元函数

c++ - 在 C/C++ 源代码中包含 Git 提交哈希和/或分支名称

c++ - C++- “Multiple Definition of functions”如何解决?

C++重载运算符解析

Java:覆盖或重载方法?

html - 根据 TextMate 中的属性修改 HTML 语法

c++ - 在运行时加载语法

delphi - 如何从DLL导出重载函数?