分配器:标准容器如何在内部工作?

sky*_*ack 4 c++ containers stl allocator

作为这个问题的一个例子,我将使用std::vector.
文件定义如下:

template<class T, class Allocator = std::allocator<T>>
class vector;
Run Code Online (Sandbox Code Playgroud)

正如所料,如果T是它的类型,分配器应该偏向于T.
无论如何,下面的代码编译没有错误(至少,使用GCC)并运行:

#include<vector>
#include<memory>
#include<string>

struct S {
    int i;
    double d;
    std::string s;
};

int main() {
    std::allocator<int> alloc;
    std::vector<S, std::allocator<int>> v{alloc};
    v.push_back(S{});
}
Run Code Online (Sandbox Code Playgroud)

在这里,我创建一个向量小号通过专注于一个allocator INT.

这是合法代码吗?我应该期待未定义的行为吗?还有什么?
我不完全明白这背后的魔力以及为什么STL让用户这样做.
另一方面,rebind仅在文档中提及类似的事情std::list,我不知道它们是否也适用于这种情况.

在其他方面,如果它有效,我想知道它为什么有效(它rebind背后是什么?),否则我想知道为什么它被允许.

How*_*ant 7

表98 - 分配器感知容器要求在第一行中说:

要求: allocator_type::value_type与...相同X::value_type

客户端代码违反Requires子句会导致未定义的行为.

gcc和VS不会检测到此错误.它们允许代码通过将分配器重新绑定到适当的类型来工作.libc ++使用a主动检测此错误static_assert.

http://melpon.org/wandbox/permlink/LVYEHfVIGoyZsii8

vector在这方面,所有三种实现都是有效的.

libc ++主动检测此错误的基本原理是更快地(以及在编译时)为您找到错误.如果在一个大型程序中你有两个向量,那将是一件坏事: vector<int, some_allocator<int>>并且vector<int, some_allocator<long>>程序逻辑假设它们是相同的类型.