C++映射不同类型的分配重载
C++ map assignment overload for different types
我有一个自定义类,它继承自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
。
- 正在尝试重载二进制搜索树分配运算符
- 为什么我可以在不重载 "=" 运算符的情况下将一个对象分配给另一个对象?
- 使用操作重载对象重新分配对象
- 我重载了 << 和 = 运算符。为什么当我将一个对象分配给另一个对象并尝试打印它时,我会被打印出来?
- 如何重载逗号运算符以将值分配给数组
- 动态分配自定义类的数组和重载运算符
- 我的移动分配操作程序重载的分段错误
- 具有预分配结果C++的重载加运算符
- clang++ 8.0.1 自分配重载警告
- 模板化 += 运算符重载与 std::p air 分配
- 即使我重载了分配,也没有可行的重载'='错误
- 如何使用堆分配进行运算符++重载
- C++ - 重载'=',用于将十六进制值分配给对象
- 无法在重载运算符时将数组元素分配给类变量"="
- 基于TypeName的专业分配运算符重载
- 将重载函数分配给功能指针作为默认值
- 重载分配操作/流
- c++重载运算符+和动态内存分配
- C++映射不同类型的分配重载
- 使用动态内存分配重载istream操作符