我有一个继承自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_?
答:不,谢谢,这是我需要做的。
答案 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] = c
为c
时,这将允许_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
。