不同类型的C ++映射赋值重载

时间:2014-12-16 17:22:29

标签: c++ operator-overloading overloading unordered-map

我有一个继承自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

现在,如果我想存储矢量&lt; ...&gt; _pointer在我的地图上我可以做到:

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

它有效,但我希望能够做到这一点:

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

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

我试过这样做(通过重载operator [],operator =)但似乎我不会去某个地方。任何人都可以建议我实现这种行为吗?

感谢。

常见问题:

  

问:为什么在标识符名称上使用_?难道你不知道这是不好的做法吗?   答:手头的问题无关紧要。

     

问:您的代码不是RAII   A:那么,是什么?

     

问:你为什么不使用unique_ptr / smart_ptr?你为什么要直接处理指针?   答:因为我需要,而且对于手头的问题也无关紧要。

     

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

2 个答案:

答案 0 :(得分:11)

单独重载operator[]并不是一种完全直接的方法。让我解释一下原因。

a[b] = c;属于带有重载a的类型时,说operator[]等同于说a.operator[](b) = c;。请注意,操作员不了解c及其类型。在典型的标准库容器中,operator[]返回value_type &。这允许赋值语法,因为引用是左值。您所做的就是为容器中已存在的对象分配新值。

应该清楚为什么你不能合理地超载operator[]来做你想做的事情:你不能根据回报价值超载,那只是方式各种operator[]重载会有所不同,因为大概他们都需要以string作为参数。

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

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

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

答案 1 :(得分:0)

你的_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