【问题标题】:no overloaded function found未找到重载函数
【发布时间】:2021-12-17 22:54:55
【问题描述】:

我有来自第三方的KeyA 类,将成为使用的关键。当我定义一个“

error: no match for ‘operator<’ (operand types are ‘const KeyA’ and ‘const KeyA’)

一些显示问题的简化代码:

#include <map>
using namespace std;

struct KeyA {  // defined in somewhere else
    int a;
};

namespace NS {
struct config {
    using Key = KeyA; // type alias
    using Table = map<Key, int>;
};

bool operator <(const config::Key& lhs, const config::Key& rhs) {
    return lhs.a <rhs.a ;
}
}

int main()
{
    using namespace NS;
    config::Table table;
    table[{1}]= 2;

    return 0;
}

这里发生了什么?以及如何解决这个问题(无法触及KeyA,很可能必须将重载函数保留在NS)?

【问题讨论】:

  • NS 是我必须忍受的约束。 :-(
  • 在你的键结构中将操作符设置为好友
  • 为什么不能在与KeyA 相同的命名空间中定义operator&lt;?您不必为此修改KeyA
  • 对不起,“KeyA”是一些不可触及的生成代码;而且我只能在“NS”中更改

标签: c++ namespaces operator-overloading type-alias


【解决方案1】:

一个简单的选择是定义您自己的比较器并将其提供给std::map 模板参数:

struct config
{
    using Key = KeyA; // type alias

    struct KeyLess {
        bool operator ()(const Key& lhs, const Key& rhs) const {
            return lhs.a < rhs.a;
        }
    };

    using Table = map<Key, int, KeyLess>;
};

如果需要,您可以将其他比较功能留在那里。我删除了它,因为看起来你只是为地图定义了它。

【讨论】:

  • 这是一种解决方案,但出于某些限制,我不能添加“less”作为输入。实际上我有一些带有这个“less”的代码,然后我试图摆脱“less”,使这个表能够使用一些只需要“K,V”的模板。
  • 那么听起来你正在打破封装,将你的表传递给那些没有业务知道其底层实现的事物。
  • 一些现有的模板是基于参数编写的,例如 template void foo(std::map m);为了完成这项工作,我必须像 void foo(std::map m) 一样进行扩展。无论如何,为什么编译器找不到重载的运算符?
  • 如果你把它放在一个更好的地方它可以找到它:godbolt.org/z/aT4n5eKf5 - 这里你可以在给类型起别名之前定义运算符。
【解决方案2】:

您可以使用以下完整的工作program来解决您的问题。

#include <map>
using namespace std;

struct KeyA {  // defined in somewhere else
    int a;
    //friend declaration
    friend bool operator <(const KeyA& lhs, const KeyA& rhs);
};
bool operator <(const KeyA& lhs, const KeyA& rhs) {
    return lhs.a <rhs.a ;
}
namespace NS {
struct config {
    using Key = KeyA; // type alias
    using Table = map<Key, int>;
};


}

int main()
{
    using namespace NS;
    config::Table table;
    table[{1}]= 2;

    return 0;
}

以上程序的输出可见here

【讨论】:

  • 对不起,“KeyA”是一些不可触及的生成代码;而且我只能在“NS”中更改
  • @pepero 好的,那么应该使用 paddy 的解决方案。
猜你喜欢
  • 1970-01-01
  • 2016-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-02
  • 2014-03-06
  • 2017-09-19
相关资源
最近更新 更多