为什么操作人员超载&;()禁止存储在STL容器中的类? 突然,我看到一个声明,C++标准禁止使用STL容器存储类元素,如果该类有过多的操作符和() < /P>

为什么操作人员超载&;()禁止存储在STL容器中的类? 突然,我看到一个声明,C++标准禁止使用STL容器存储类元素,如果该类有过多的操作符和() < /P>,c++,stl,operators,operator-overloading,C++,Stl,Operators,Operator Overloading,重载了操作符&(),但看起来像是一个默认的“address of”操作符,可以很容易地通过使用,并且被认为是可移植的标准编译器 为什么在存在boost::addressof()解决方案的情况下,存储在STL容器中的类禁止使用重载的运算符(&())是在一元前缀和不过载的要求之后发明的,用于存放在std库容器中的对象 我模模糊糊地记得Pete Becker(当时在Dinkumware的标准库实现中工作)曾经说过,如果每个人都超载了操作员的地址,并且希望他们的标准库实现仍然有效,那么就应该通过实现一个

重载了
操作符&()
,但看起来像是一个默认的“address of”操作符,可以很容易地通过使用,并且被认为是可移植的标准编译器


为什么在存在
boost::addressof()
解决方案的情况下,存储在STL容器中的类禁止使用重载的
运算符(&()
)是在一元前缀
不过载的要求之后发明的,用于存放在std库容器中的对象


我模模糊糊地记得Pete Becker(当时在Dinkumware的标准库实现中工作)曾经说过,如果每个人都超载了操作员的地址,并且希望他们的标准库实现仍然有效,那么就应该通过实现一个标准库来惩罚他们

可能是因为仅仅禁止使用重载运算符&()类比创建std::addressof()函数并用它替换容器中的所有代码要简单。

该标准于1998年最终确定,并于2003年进行了修复,而
boost::addressof
则于2002年初完成

此外,
addressof
是否是答案还不清楚。
运算符(&()
的重载表示应该避免使用原始指针。
Allocator::address
成员提供了从
Allocator::reference
Allocator::pointer
的最佳接口,因此在一般理论上,您应该能够有效地将
运算符&
重写引入到具有自定义分配器的其他性能良好的类中

考虑到引用几乎完成了指针所做的一切,而分配器接口抽象了其他一切,因此不需要原始指针

对库实现者的方便性不应该是一个问题。
Allocator::pointer
的定义不正确的语义是一个问题,到目前为止,我在C++0x中读到的内容并没有澄清这一点

C++0x从CopyConstructible中删除了对
操作符&
的任何提及,而且对于容器参数根本不需要任何可构造的内容-用户可以坚持使用
emplace
。即使是
vector
也只需要Destructible,尽管我认为实际使用
insert
erase
需要更多


(请注意,在最严格的阅读中,C++03中不禁止重载。您只是不允许更改内置项的值或类型。)

出于好奇(没有批评,实际上只是好奇),您会在哪里重载运算符的地址?@roe:在像ATL::CComPtr()这样的类中,这很有意义。您经常使用它们而不是原始指针。您希望为CComPtr调用类似于
HRESULT GetStuff(IInterface**)
的函数,并且需要有一个方法来检索封装指针的地址,或者重载
运算符(&()
。快速浏览标准中关于容器的章节后,我没有找到这样的声明。免责声明:我刚刚浏览了一遍,如果不是用粗体字母和/或句首,我可能会错过它:)@David:CopyConstructible requirements(20.1.3)指定
&t
的类型为
t*
,并且“表示
t
的地址”。从技术上讲,这并不禁止重载运算符,但确实禁止更改其行为。@Mike:谢谢,这就是当您浏览文档时发生的情况:)这确实让人想知道为什么首先允许重载运算符的地址,不是吗?@MadKeithV:当运算符重载被“发明”时对于C++,必须决定哪些运算符应该是可重载的,哪些不应该是可重载的。因为那时没有任何经验-至少不是C++的,所以必须猜测。事后看来,批评这些猜测很容易。(尽管如此,因为它确实被使用了,有人会认为重载一元前缀
&
是有用的和有益的。)VS2010团队无论如何都在重写整个STL。这不是争论。根据提到的帖子,这是未定义的行为。(- 1)VS2010团队是否指定C++标准,我认为这更是一个为什么标准是什么的问题?另一个答案可能更好,那就是它是一个历史性的东西。“该标准于1998年最终确定”于1997年。