突然在这篇文章("问题2")中,我看到了一句话,即C++标准禁止使用STL容器存储类的元素,如果该类有重载的operator&()
。
虽然重载operator&()
确实可能会有问题,但似乎可以通过一组在boost::addressof()
中使用的肮脏的转换来轻松使用默认的“取地址”操作符,并且被认为是可移植和标准兼容的。
为什么对于存储在STL容器中的类而言,具有重载operator&()
是被禁止的,而boost::addressof()
的解决方法存在呢?
突然在这篇文章("问题2")中,我看到了一句话,即C++标准禁止使用STL容器存储类的元素,如果该类有重载的operator&()
。
虽然重载operator&()
确实可能会有问题,但似乎可以通过一组在boost::addressof()
中使用的肮脏的转换来轻松使用默认的“取地址”操作符,并且被认为是可移植和标准兼容的。
为什么对于存储在STL容器中的类而言,具有重载operator&()
是被禁止的,而boost::addressof()
的解决方法存在呢?
没有查看链接,我猜测 boost::addressof()
中的技巧是在不重载一元前缀 &
的要求之后发明出来的,以便容纳 std lib 容器中的对象。
我模糊地记得 Pete Becker(当时在 Dinkumware 上为他们的标准库实现工作)曾经说过,每个重载地址运算符并希望他们的标准库实现仍然正常工作的人都应该被惩罚,让他们实现一个可以这样做的标准库。
可能是因为禁止使用重载运算符&()类比创建std::addressof()函数并用它替换容器代码中的每个&使用起来更轻松。
该标准于1998年完成,2003年进行了修正,而boost::addressof
可以追溯到2002年初。
此外,不清楚addressof
是否是答案。 operator&()
的重载表明应避免使用原始指针。 Allocator::address
成员提供了从Allocator::reference
到Allocator::pointer
的最佳接口,因此在一般理论中,您应该能够有效地通过自定义分配器引入一个operator&
覆盖到一个行为良好的类中。
考虑到引用几乎可以执行指针所做的所有操作,而分配器接口抽象了其他所有内容,因此不需要使用原始指针。
方便库实现者不应成为问题。 Allocator::pointer
的语义不明确是一个问题,我在C++0x中所读到的并没有解决这个问题。
C++0x从CopyConstructible中删除了对operator&
的任何提及,而且完全不需要对容器参数进行任何构造 - 用户可以使用emplace
。即使是vector
也只需要Destructible,尽管我认为实际使用insert
或erase
需要更多。
(请注意,在最严格的解读中,C++03中并没有禁止重载。你只是不能改变内置类型的值或类型。)
HRESULT GetStuff(IInterface**)
这样的函数调用可以用于 CComPtr<IInterface>,这需要有一种方法来检索封装指针的地址或重载operator&()
。 - sharptooth&t
的类型为T*
,且“表示T
的地址”。这在技术上并不禁止重载运算符,但是禁止改变其行为。 - Mike Seymour