C++自定义分配器大小参数作为模板参数会引发编译器错误
C++ custom allocator size argument as template parameter throws compiler error
当我为容器使用自定义分配器时,以下代码给了我预期的结果(将大小 sz 保留为全局变量(
#include <cstddef> /* size_t */
#include <new> /* Only for bad_alloc */
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
using std::endl;
std::size_t constexpr sz = 4;
template <typename T> class StaticAllocator {
protected:
static T buf[sz];
public:
typedef T value_type;
T* allocate(std::size_t const n) {
if (n > sz) throw std::bad_alloc();
return buf;
}
void deallocate(T*, std::size_t) {}
};
template<typename T> T StaticAllocator<T>::buf[sz];
int main(void) {
std::vector<char, StaticAllocator<char> > v;
v.push_back('a');
v.push_back('b');
for (auto const& i : v) cout << i << endl;
}
当我尝试将大小用作类的模板参数时,此版本的代码会给我编译器错误
#include <cstddef> /* size_t */
#include <new> /* bad_alloc */
#include <vector>
using std::vector;
#include <iostream>
using std::cout;
using std::endl;
template<typename T, std::size_t sz> class StaticAllocator {
protected:
static T buf[sz];
public:
typedef T value_type;
T* allocate(std::size_t const n) {
if (n > sz) throw std::bad_alloc();
return buf;
}
void deallocate(T*, std::size_t) {}
};
template<typename T, std::size_t sz> T StaticAllocator<T, sz>::buf[sz];
int main(void) {
std::vector<char, StaticAllocator<char, 4> > v;
v.push_back('a');
v.push_back('b');
for (auto const& i : v) cout << i << endl;
}
T
的分配器获取某些类型U
的分配器,请使用成员别名模板std::allocator_traits::rebind_alloc<U>
[allocator.traits.types]:
Alloc::rebind<T>::other
Alloc::rebind<T>::other
是否有效,并且 表示类型;否则,Alloc<T, Args>
Alloc
是否是形式Alloc<U, Args>
的类模板实例化,其中Args
是零个或多个类型参数;否则,rebind_alloc
的实例化格式不正确。
请注意,Args
是类型模板参数。在您的分配器中没有rebind
.在第一种情况下,使用Alloc<U>
,Args
为空。但在第二种情况下,第二个模板参数是非类型参数,它不能与Args
匹配。
您需要手动添加rebind
成员结构:
template<typename T, std::size_t sz>
class StaticAllocator {
// ...
template<class U>
struct rebind {
using other = StaticAllocator<U, sz>;
};
};
另请注意,对于某些常规类型S
,您的分配器已损坏。首先,默认情况下将初始化buf
构造sz
对象S
。然后,在破坏现有S
之前,它将被在同一位置的新构造覆盖。重新分配时也会发生类似的事情。这可能导致未定义的行为。有关一些详细信息,请参阅此和此问题。
在现已删除的答案中提出了以下解决方案:从std::allocator<T>
继承:
template<typename T, std::size_t sz> class StaticAllocator :
public std::allocator<T> {
// ...
};
代码编译并运行,但是...不调用StaticAllocator::allocate
和StaticAllocator::deallocate
(至少在libstdc++中(。原因是内部std::vector
总是使用rebind
来获取分配器类型:
using Tp_alloc_type =
typename gnu_cxx::alloc_traits<Alloc>::template rebind<Tp>::other;
rebind
是从std::allocator<T>
继承的,它返回std::allocator
而不是StaticAllocator
。这就是为什么您仍然必须在StaticAllocator
中提供自己的rebind
。
- C++声明模板参数阴影模板参数错误
- 为什么 CRTP 模板C++给出无效参数错误?
- (C/C++)fscanf_s从txt文件以字符形式读取数组时缺少整数参数错误
- 参数错误可能与类型不匹配有关?
- printf 和 strftime 的参数错误无效
- 如何修复"ctypes"。参数错误:参数 2:<键入"异常.类型错误">:RaspberryPi 中的错误类型"错误
- 如何修复"没有重载函数需要 2 个参数"错误C++
- 术语不计算为函数采用 1 个参数错误?
- 从带有 getline() 的文件读入一行上有多个信息得到无效参数错误
- 为什么我不能像使用 std::string::size_type 那样使用 QList::size_type?(模板参数错误)
- cudaFreeHost() 无效参数错误
- 精神语法不会编译:函数模板参数错误?
- C 功能具有参考参数错误的迭代器错误.寻求解释
- 使用getDefaultCommConfig使用无效的参数错误
- C++ 可变参数模板和模板模板参数:错误:模板参数列表中参数 1 处的类型/值不匹配
- 使用SWIG生成的Python库时,向量分配器参数错误
- 错误C2664:无法转换参数错误
- C 作为参数错误的功能
- 命令行参数错误
- 增强Python参数错误