如何解决结构体中嵌入的运算符重载的歧义? [英] How to solve ambiguity in operator overloading embedded inside a struct?

查看:82
本文介绍了如何解决结构体中嵌入的运算符重载的歧义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在以下代码中,令人惊讶的是,当g ++编译器嵌入到结构中以用作集合中的比较器参数时,它们无法决定使用哪个运算符:

In the following code, the g++ compiler surprisingly cannot decide which operator to use when they are embedded in a struct to serve as a comparator argument in a set:

#include <string>
#include <set>

struct KeyWord {
  std::string str;
  int qt;
  KeyWord(const std::string aKw = "", const int aQt = 0) : str(aKw), qt(aQt) {}
};

struct CompareKeywords {
  bool operator() (const std::string& left, const std::string& right) const {
    if (left.size() > right.size()) return true;
    else if (left.size() < right.size()) return false;
    else return (left < right);
  }
  bool operator() (const KeyWord& left, const KeyWord& right) {
    if (left.str.size() > right.str.size()) return true;
    else if (left.str.size() < right.str.size()) return false;
    else return (left.str < right.str);
  }
};

int main() {
  std::set<std::string, CompareKeywords> a;
  std::set<KeyWord, CompareKeywords> b;
  std::string s("_s_");
  KeyWord k("_k_", 1);
  a.insert(s);
  b.insert(k);
}

这是编译器的输出:

g++ oa.cpp
/usr/include/c++/4.9/bits/stl_tree.h: In instantiation of ‘std::pair<std::_Rb_tree_node_base*, std::_Rb_tree_node_base*> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_get_insert_unique_pos(const key_type&) [with _Key = std::basic_string<char>; _Val = std::basic_string<char>; _KeyOfValue = std::_Identity<std::basic_string<char> >; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::key_type = std::basic_string<char>]’:
/usr/include/c++/4.9/bits/stl_tree.h:1498:47:   required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = std::basic_string<char>; _Val = std::basic_string<char>; _KeyOfValue = std::_Identity<std::basic_string<char> >; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >]’
/usr/include/c++/4.9/bits/stl_set.h:502:29:   required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::basic_string<char>; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<std::basic_string<char> >; std::set<_Key, _Compare, _Alloc>::value_type = std::basic_string<char>]’
oa.cpp:28:13:   required from here
oa.cpp:11:8: note: candidate 1: bool CompareKeywords::operator()(const string&, const string&) const
   bool operator() (const std::string& left, const std::string& right) const {
        ^
oa.cpp:16:8: note: candidate 2: bool CompareKeywords::operator()(const KeyWord&, const KeyWord&)
   bool operator() (const KeyWord& left, const KeyWord& right) {
        ^
oa.cpp:11:8: note: candidate 1: bool CompareKeywords::operator()(const string&, const string&) const
   bool operator() (const std::string& left, const std::string& right) const {
        ^
oa.cpp:16:8: note: candidate 2: bool CompareKeywords::operator()(const KeyWord&, const KeyWord&)
   bool operator() (const KeyWord& left, const KeyWord& right) {
        ^
/usr/include/c++/4.9/bits/stl_tree.h: In instantiation of ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_(std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr, const _Val&) [with _Key = std::basic_string<char>; _Val = std::basic_string<char>; _KeyOfValue = std::_Identity<std::basic_string<char> >; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::basic_string<char> >; std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_Base_ptr = std::_Rb_tree_node_base*]’:
/usr/include/c++/4.9/bits/stl_tree.h:1502:38:   required from ‘std::pair<std::_Rb_tree_iterator<_Val>, bool> std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::_M_insert_unique(const _Val&) [with _Key = std::basic_string<char>; _Val = std::basic_string<char>; _KeyOfValue = std::_Identity<std::basic_string<char> >; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >]’
/usr/include/c++/4.9/bits/stl_set.h:502:29:   required from ‘std::pair<typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator, bool> std::set<_Key, _Compare, _Alloc>::insert(const value_type&) [with _Key = std::basic_string<char>; _Compare = CompareKeywords; _Alloc = std::allocator<std::basic_string<char> >; typename std::_Rb_tree<_Key, _Key, std::_Identity<_Key>, _Compare, typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Key>::other>::const_iterator = std::_Rb_tree_const_iterator<std::basic_string<char> >; std::set<_Key, _Compare, _Alloc>::value_type = std::basic_string<char>]’
oa.cpp:28:13:   required from here
oa.cpp:11:8: note: candidate 1: bool CompareKeywords::operator()(const string&, const string&) const
   bool operator() (const std::string& left, const std::string& right) const {
        ^
oa.cpp:16:8: note: candidate 2: bool CompareKeywords::operator()(const KeyWord&, const KeyWord&)
   bool operator() (const KeyWord& left, const KeyWord& right) {
        ^

最后一行显示了编译器显示两个候选对象时的歧义.

The last lines show the ambiguity where the compiler shows two candidates.

为什么存在这种歧义?我应该怎么压抑它?

Why this ambiguity exist? How should I supress it?

推荐答案

gcc的某些版本似乎具有这种特有的功能,可以将这些消息突然打印出来.例如,所有内容都基于coliru 执行.

It looks like some builds of gcc have this peculiar feature of printing these messages out of the blue. For example all builds on coliru do this.

这些消息不是错误,因为生成了目标文件,它们也不是警告,因为-Werror不会将它们变成错误.它们看起来像是编译器错误.显然,不能使用编译器标志来抑制这些非警告.

These messages are not errors because the object file is produced, and they are not warnings because -Werror doesn't turn them into errors. They look rather like a compiler bug. Obviously one cannot suppress these non-warnings with compiler flags.

与我的计算机上的gcc完全相同的版本不会打印任何带有 this 代码的消息.它们确实使用类似代码打印常规(带有彩色警告",不可抑制但易出错的警告)警告.

Same exact versions of gcc on my machine don't print any messages with this code. They do print regular (tagged with the coloured "warning", non-suppressible, but turnable-to-error) warnings with similar code.

在coliru上,使第二个operator() const 禁止显示消息

On coliru, making the second operator() const suppresses the messages.

这篇关于如何解决结构体中嵌入的运算符重载的歧义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆