C++ map key 指针

Q
我对在 map 中用作键时如何处理指向自定义对象的指针有疑问。更具体地说,如果我定义

std::map< CustomClass*, int > foo;

默认的 C++ 实现是否可以处理这些指针?或者我是否需要定义一个自定义比较器函数来处理它?通常,使用指向对象的指针作为键是一种好习惯吗?

A1
默认实现将比较指针存储的地址,因此不同的对象将被视为不同的键。但是,不会考虑对象的逻辑状态。例如,如果您使用std::string *as 键,则std::string具有相同文本的两个不同对象"Hello"将被视为不同的键!(当按地址存储在地图中时)

只要您理解上面的重要区别,就可以使用指针作为键。

A2
指针将被处理,但作为指针进行比较(内存顺序)。less如果你想比较对象,你必须传递自定义仿函数:

template struct ptr_less 
{
    bool operator()(T* lhs, T* rhs) 
    {
        return *lhs < *rhs; 
    }
};
map> myMap;

A3
指针可以用作键,但我不建议使用 std::map(或 std::set)。该程序的行为是不确定的,即当一个人遍历地图时,地图中的项目被迭代的顺序不能保证是相同的。这实际上取决于对象(键)的内存地址。看一下这个例子,正如您所看到的,无论在地图中的插入顺序如何,当键是字符串而不是指针时,项目都以确定的方式迭代。

#include 
#include 
using namespace std;

class SomeClass {
    public:
    SomeClass(const std::string& name): m_name(name) {}
    std::string GetName()const {return m_name; }
    bool operator <(const SomeClass& rhs) const { return m_name < rhs.m_name; }
    private:
    std::string m_name;
};

auto print_seq  = [](const auto& seq) { for (const auto& itr: seq) {std::cout << itr.second << " , ";} std::cout << std::endl;};

int main() {
    // your code goes here
    std::map pointer_keyed_map;
    SomeClass s3("object3");
    SomeClass s1("object1");
    SomeClass s2("object2");
    pointer_keyed_map.insert(std::make_pair(&s1, s1.GetName()));
    pointer_keyed_map.insert(std::make_pair(&s2, s2.GetName()));
    pointer_keyed_map.insert(std::make_pair(&s3, s3.GetName()));
    std::cout << "Pointer based keys: object order" << std::endl;
    print_seq(pointer_keyed_map);

    std::map int_keyed_map;
    int_keyed_map.insert(std::make_pair(s3, s3.GetName()));
    int_keyed_map.insert(std::make_pair(s1, s1.GetName()));
    int_keyed_map.insert(std::make_pair(s2, s2.GetName()));
    std::cout << "String based keys: object order" << std::endl;
    print_seq(int_keyed_map);
    return 0;
}

你可能感兴趣的:(c++,开发语言,算法)