C++映射不同类型的分配重载

C++ map assignment overload for different types

本文关键字:分配 重载 同类型 映射 C++      更新时间:2023-10-16

我有一个自定义类,它继承自unordered_map,如下所示:

class _map : public unordered_map<string, _pointer> {
    public:
    // STUFF ...
};

假设_pointer是另一个自定义类,它的作用是帮助我处理指针内容。 例如,_pointer可以从许多不同的预定义类型构造:

vector<...> v;
_pointer p = _pointer(v);
// p is now a _pointer holding v and vector<...> data

现在,如果我想在地图上存储 vector<...> _pointer s,我可以简单地做:

_map map;
vector<...> v;
map["a_vector"] = _pointer(v);

它有效,但我希望能够这样做:

_map map;
vector<...> v;
map["a_vector"] = v;

并自动将其分配为_pointer(v),也许是通过重载map分配内容的方式,并通过调用特定的_pointer构造函数来明确告诉它处理vector<...>

我已经尝试这样做(通过重载运算符[],运算符=(,但似乎我并没有去某个地方。谁能建议我实现这种行为的方法?

谢谢。

常见问题:

问:为什么在标识符名称上使用 _?你不知道这是不好的做法吗?
答:对于手头的问题来说,这并不重要。

问:您的代码不是 RAII。
答:那又如何?

问:为什么不使用unique_ptr/smart_ptr?为什么要直接处理指针?
答:因为我需要,这对手头的问题也不重要。

问:为什么要超载unordered_map?你为什么不使用这个_OTHER_OPTION_?
答:不,谢谢,这是我需要做的。

没有

一种完全直接的方法可以通过单独重载operator[]来做到这一点。 让我解释一下原因。

a属于具有重载operator[]的类型时说a[b] = c;相当于说a.operator[](b) = c;。 请注意,运算符不知道c,也不了解其类型。在典型的标准库容器中,operator[]返回一个value_type & 。这允许赋值语法,因为引用是左值。您所做的只是为容器中已存在的对象分配一个新值。

应该清楚为什么你不能合理地重载operator[]做你想做的事情:你不能基于返回值重载,这是各种operator[]重载不同的唯一方式,因为大概它们都需要将string作为参数。

即使您尝试将运算符实现为 template <typename T> T & operator[](string key); 仍然会遇到问题,因为类型推断不适用于返回类型。你必须写出a.operator[]<decltype(c)>(b) = c;,这太讨厌了。

话虽如此,有一个选项有点笨拙,但可行:让你的operator[]返回一个代理对象,类似于std::vector<bool>::operator[]()采取的方法。 代理类型需要具有:

  • operator _pointer *&()(和operator _pointer *() const(,以便它可以在需要_pointer *的上下文中使用。(这些是隐式转换运算符
  • proxy_type & operator=(_pointer *)以便可以直接分配新值。(这将允许a[b] = c在地图上工作,当c_pointer *
  • 要接受的任何其他类型的赋值运算符。 如果你能接受任何东西,那么template <typename T> proxy_type & operator=(T const &);例如。 这将处理您当前尝试实施的情况。
  • 如果您希望代理类型在取消引用时的行为类似于_pointer *,则可能_pointer * operator->()_pointer & operator*()

您的_pointer构造函数就足够了...如果您实际定义了一个

#include <string>
#include <map>
#include <vector>
using namespace std;
class Foo{
    int _ent;
public:
    Foo() : _ent(0) {}
    Foo(int ent) : _ent(ent) {}
    Foo(const vector<int>& ents) : _ent(ents.front()) {}
    void printEnt() const{cout << _ent << ' ';}
};
int main()
{
    map<string, Foo> bar;
    vector<int> v{10, 20, 30, 40, 50};
    bar["blah"] = 13;
    bar["bleck"] = v;
    bar["blah"].printEnt(); // prints 13
    bar["bleck"].printEnt(); // prints 10
    return 0;
}

我怀疑问题是您没有定义与您尝试分配的vector匹配的构造函数。

如果您正在尝试制作一个通用指针类(AKA C++的自动指针(,那么您肯定想要模板化_pointer