提供模板类的一种方法的定义

时间:2015-01-15 20:07:33

标签: c++ templates c++11

是否可以提供模板类的其中一种方法的自定义定义。或者它是全部还是全无,意味着我必须按原样使用所有提供的定义,或者我必须创建/定义整个类的模板特化。

我正在编写一些测试代码,以便更好地理解编写自定义分配器。我想提供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()。方法原型是否在其中一个基类中?

2 个答案:

答案 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

如果要自定义行为,则需要提供自己的分配器实现。