是否可以提供模板类的其中一种方法的自定义定义。或者它是全部还是全无,意味着我必须按原样使用所有提供的定义,或者我必须创建/定义整个类的模板特化。
我正在编写一些测试代码,以便更好地理解编写自定义分配器。我想提供allocator :: allocate()的自定义定义。我是否必须转发声明分配器。或者我有alloc()的原型错了吗?或者我必须为allocator提供模板特化,这样我就可以提供自己的allocate()定义。
#include <memory>
#include <iostream>
template <>
std::allocator<int>::pointer
std::allocator<int>::allocate(size_type n, std::allocator<void>::const_pointer hint)
{
cout << "Doing an alloc for an int allocator" << endl;
return nullptr;
}
int main()
{
std::allocator<int> a1; // default allocator for ints
int* a = a1.allocate(10); // space for 10 ints
}
收到以下错误:
$ g++ -std=c++11 ./t1.cc
./t1.cc:6:78: error: no member function 'allocate' declared in 'std::allocator<int>'
我正在使用g ++ 4.7.2。我查看了头文件&#34; bits / allocator.h&#34; (包含自&#34;内存&#34;其中定义了类分配器。没有看到方法allocate()。方法原型是否在其中一个基类中?
答案 0 :(得分:0)
那是因为在gcc中,allocator
因此被定义为:
template<typename _Tp>
class allocator: public __glibcxx_base_allocator<_Tp>
{ .. };
allocate()
方法本身来自__glibcxx_base_allocator
。现在基数是几行之后,刚刚删除:
// Undefine.
#undef __glibcxx_base_allocator
因为阻止像你这样的人在代码中捣乱而气馁!
但是,让我在前面加上不要这么做OMG ,为了解决这个问题,你可以发现__glibcxx_base_allocator
#define
为{ {1}},你可以使用这些知识来专门化你的功能(请注意,它必须与原始模板在同一名称空间中 - 按照专业化规则):
__gnu_cxx::new_allocator
我真的无法强调 NOT DO THIS 。但追踪是很有趣的。
答案 1 :(得分:0)
查看MinGW g ++ 4.9附带的libstdc ++标头,allocate
成员函数的定义出现在标题new_allocator
中定义的类ext/new_allocator.h
中。 std::allocator
公开继承自new_allocator
。
如果选择libstdc ++将allocate
定义为std::allocator
本身的成员函数,您的代码将被编译(它在VS2013上编译,因为std::allocator
的实现确实定义了{{ 1}}成员函数),但即便如此,它也将是未定义的行为。
来自N3337,§17.6.4.2.1/ 2 [namespace.std]
如果C ++程序声明了,那么它的行为是不确定的 - 标准库类模板的任何成员函数的明确特化,或
allocate
如果要自定义行为,则需要提供自己的分配器实现。