为什么Allocator::reference被逐步淘汰
Why is Allocator::reference being phased out?
所以我正在查看std::vector
的规范,并注意到reference
的类型定义从c++ 03中的Allocator::reference
变为c++ 11中的value_type&
。我很惊讶,所以我开始深入调查。
在c++ 03§20.1.5中[lib.allocator.]在表32中,X::reference
被定义为T&
, X::const_reference
被定义为T const&
。
然而,在c++ 11§17.6.3.5中[allocator.]表28中缺少reference
和const_reference
。
接下来,我们在c++ 11中添加了§20.6.8 std::allocator_traits
,其中不包括reference
。但是§20.6.9 std::allocator
可以。
最后是§23.2.1 [container.requirements]。其中定义X::reference
为"T
的左值",X::const_reference
为"T
的const左值"。
所以,我在谷歌上找到了这篇论文(1,2),它建议从分配器需求中删除reference
,但它没有提到它背后的任何理由。但是也有一个LWG的问题反对这一改变。
此外,我还发现了Alexander Stepanov的采访,他谈到了reference
如何封装特定于机器的内存布局,以及Herb Sutter的帖子,他谈到了容器元素的指针,容器需求以及std::vector<bool>
如何不是容器。
那么,你怎么看这一切?reference
有用吗?它达到目的了吗?"花哨"的引用如何符合标准?这是一个大胆的举动,完全消除它们,使更严格的容器要求和弃用std::vector<bool>
吗?
因为嵌套的类型定义是多余的。Scott Meyers的Effective STL,第49页:
标准明确地允许库实现者这样假设每个分配器的指针类型是T*和every的同义词allocator的引用类型定义与T&
相同。
http://en.wikipedia.org/wiki/Allocator_ (C % 2 b % 2 b)
它们最初的目的是使库更灵活,独立于底层内存模型,允许程序员在库中使用自定义指针和引用类型。然而,在将STL纳入c++标准的过程中,c++标准化委员会意识到,对内存模型的完全抽象将导致无法接受的性能损失。为了解决这个问题,对分配器的要求进行了更严格的限制。因此,分配器提供的定制级别比Stepanov最初设想的要有限得多。"
最初,它们被设计为抽象出内存本身,允许一个人通过互联网连接在另一台机器上分配内存,并使用指针/引用来回复制数据以跟踪实时情况。类似地,可以在纯c++中创建类似java的GC。这种抽象似乎是一个惊人的想法!
但是,这会导致性能损失,这在当时被认为是不可接受的。而且,如果你仔细想想,用代码工作几乎是不可能的。每个void func(const string&)
都必须变成template<class allocator> void func(allocator::reference)
,这是一个不可推导的上下文,因此您必须在函数调用(func<std::allocator<std::string>::const_reference>(username)
)中显式地编写分配器,没有人会这样做,这会使GC无法正常工作。现在,分配器仅仅抽象了内存分配/释放。
在对Alexander Stepanov的采访中,他提到在将STL添加到标准库的提议中,他被要求创建一个内存模型的抽象。因此,分配器诞生了。在LWG问题中有一个实现示例,其中自定义分配器的reference
被定义为T __far&
。
但是,由于未知的原因,因为我没有那么多的时间来搜索,c++ 03标准在§20.1.5 p4中有以下文本:
本国际标准中描述的容器的实现允许假设它们的Allocator模板形参满足表32之外的以下两个附加要求。
-给定分配器类型的所有实例都必须是可互换的,并且总是比较相等对方。
- typepedef成员指针、const_pointer、size_type和difference_type是要求分别为T*、T const*、size_t和ptrdiff_t。
这有效地破坏了自定义内存模型分配器与标准容器互操作的能力。
在我搜索所有提到"分配器"一词的c++ 11之前的论文时,我发现了一个主要的共识,即从标准中删除这些词。最后,本文建议通过以下注释来删除它们:
黄鼠狼的话不见了。举起你的酒杯,干杯。
胜利?我们的记忆模型终于可以疯狂了吗?没有那么多。除此之外,同一篇论文还建议将reference
从分配器需求中删除。而且看起来它已经被选为标准了。
我之前提到的LWG问题反对更改,但它以以下声明结束:
没有一致意见做出改变
所以看起来分配器最初的目的在今天不那么重要了。维基百科是这么说的:
分配器当前的目的是让程序员控制容器内的内存分配,而不是适应底层硬件的地址模型。事实上,修订后的标准消除了分配器表示c++地址模型扩展的能力,正式地(并且故意地)消除了它们的原始目的。
最后,Container::reference
与分配器无关。它的创建是为了允许实际上不是容器的代理集合。所以它就留在这里了。顺便说一下,这似乎是标准中结束语违背初衷的又一个例子。
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- Visual Studio Code "undefined reference to `WinMain@16'"
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- 使用 [] 运算符时"binding reference of type discards qualifiers"
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- Tensorflow c++ api undefined reference to 'tflite::D efaultErrorReporter()'
- 不断"Attempting to reference a deleted function"
- std::iterator::reference 必须是引用吗?
- C++/SDL "initial value of reference to a non-const must be an lvalue"
- 为什么在使用 SDL2 时仍然收到'undefined reference'链接器错误?
- OpenCV undefined reference to 'cv::imread(cv::String const&, int)'
- Libcurl c++ "undefined reference to" (Windows/MinGW/g++)
- C++返回类型 T(&)[] 与使用 reference = T(&)[] 作为返回类型
- const auto & 和 auto & if reference 对象之间的区别是 const
- 尝试使用 extern "C" 调用 C 中的C++方法,得到"undefined reference to"对象的链接器错误
- 以前的'namespace reference { }'声明
- build error : undefined reference to `yyFlexLexer::yyFlexLex
- C ++引用函数参数似乎包含原始对象的副本,而不是充当"real reference"
- 为什么Allocator::reference被逐步淘汰