我认为容器必须将它们所分配的任何分配器重新绑定到一个有效的分配器中,但是在装有LLVM(我猜的是libc ++的一部分)的STL中,似乎并非如此。这是LLVM中的错误,还是标准不需要重新绑定?
以下代码段与GCC的STL一样正常。它与clang 3.3附带的STL失败(来自MacPorts,在Mac上)。它在Linux上用clang编译好,但我认为使用与GCC相同的STL。
#include <vector>
int main()
{
std::vector<char, std::allocator<int> > c;
c.push_back(5);
}
错误是
clang++ test-rebind.cpp
In file included from test-rebind.cpp:1:
/opt/local/libexec/llvm-3.3/bin/../lib/c++/v1/vector:505:5: error: implicit instantiation of undefined template '__static_assert_test<false>'
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
^
/opt/local/libexec/llvm-3.3/bin/../lib/c++/v1/__config:412:35: note: expanded from macro 'static_assert'
typedef __static_assert_check<sizeof(__static_assert_test<(__b)>)> \
^
test-rebind.cpp:5:46: note: in instantiation of template class 'std::__1::vector<char, std::__1::allocator<int> >' requested here
std::vector<char, std::allocator<int> > c;
^
/opt/local/libexec/llvm-3.3/bin/../lib/c++/v1/__config:408:24: note: template is declared here
template <bool> struct __static_assert_test;
^
1 error generated.
答案 0 :(得分:4)
23.2.1 [container.requirements.general] / 7:
这些容器类型的所有其他构造函数都使用
Allocator&
参数(17.6.3.5),这是一个分配器,其值类型与容器的值类型相同。
所以你的代码无效。
尽管如此,以上是一个相当模糊的地方。我们可以做得更好。表99(分配器感知容器要求)在其第一行中要求容器具有allocator_type
嵌套类型,其value_type
与容器相同。 vector
(以及其他容器)的概要定义了allocator_type
:
typedef Allocator allocator_type;
换句话说,您提供的Allocator
参数负责满足要求。
答案 1 :(得分:3)
我认为容器必须将它们所分配的任何分配器重新绑定到一个有效的分配器
我无法在任何地方找到这个要求。相反,如果容器需要分配除rebind
之外的其他内容,则使用value_type
。考虑一个典型的,简化的list
实现:
template <typename T, typename A = std::allocator<T>>
class list {
struct node {
T value;
node* next;
node* prev;
};
using allocator = typename A::template rebind<node>::other;
};
我们需要使用rebind
,因为list
不会分配T
;它分配list<T>::node
s。