【问题标题】:Defining custom map comparator with non stardard signature使用非标准签名定义自定义地图比较器
【发布时间】:2019-12-14 22:24:09
【问题描述】:

假设有一个以指针为键的映射。要深入比较底层对象,可以通过以下方式编写自定义比较器:

#include <map>
#include <memory>

bool compare(std::unique_ptr<int> lhs, std::unique_ptr<int> rhs){
    return *lhs<*rhs;
}

int main(){
    std::map<std::unique_ptr<int>, short, bool (*)(std::unique_ptr<int>, std::unique_ptr<int>)> elements(compare);
}

这是无法理解的,但是为什么我需要显式传递比较回调的类型,因为它是由映射键的类型强加的?为什么不可能通过以下方式创建地图,因为它的签名应该是已知的:

std::map<std::unique_ptr<int>, short> elements(compare);

是否有需要定义不同签名的比较函数的情况?

编辑:

我想我已经回答了自己的最后一个问题。在某些时候我可以写这样的东西:

#include <map>
#include <memory>

bool compare(std::unique_ptr<BaseClass> lhs, std::unique_ptr<BaseClass> rhs){
    return *lhs<*rhs;
}

int main(){
    std::map<std::unique_ptr<DerivedClass>, short, bool (*)(std::unique_ptr<BaseClass>, std::unique_ptr<BaseClass>)> elements(compare);
}

但它没有解释为什么默认情况下不使用精确签名。

【问题讨论】:

    标签: c++ c++11


    【解决方案1】:

    为什么不能按照以下方式创建地图,因为它的签名应该是已知的

    但它并不是唯一已知的。该函数是至少两种类型的地图的有效初始化器

    std::map<std::unique_ptr<int>, short, bool (*)(std::unique_ptr<int>, std::unique_ptr<int>)>
    std::map<std::unique_ptr<int>, short, bool (&)(std::unique_ptr<int>, std::unique_ptr<int>)>
    

    函数的指针或引用在这里同样有效。两者都不是天生更好,那么如何唯一确定类型?没有立即令人信服的理由偏爱其中一个。

    还值得一提的是,std::map 的更习惯用法是倒退的。 IE。不是从比较器对象中找出类型,而是使用可以初始化对象的用户定义类型。例如:

    struct compare {
        bool operator()(std::unique_ptr<int> lhs, std::unique_ptr<int> rhs){
            return *lhs<*rhs;
        }
    };
    
    std::map<std::unique_ptr<int>, short, compare> elements;
    

    【讨论】:

      【解决方案2】:

      比较器的类型根本不是由键的类型决定的。比较器不一定是一个函数,它可以是一个类重载operator()

      事实上,第三个模板参数有一个默认参数,它就是这样一个类的实例化,即std::less&lt;Key&gt;。即std::map&lt;std::unique_ptr&lt;int&gt;, short&gt;std::map&lt;std::unique_ptr&lt;int&gt;, short, std::less&lt;std::unique_ptr&lt;int&gt;&gt;&gt;的简写

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 2022-07-22
        • 2020-03-24
        • 2016-10-20
        • 2018-12-22
        • 1970-01-01
        相关资源
        最近更新 更多