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

Provide definition of one method of a template class

本文关键字:一个 定义 方法      更新时间:2023-10-16

是否可以提供模板类方法之一的自定义定义。 或者要么全有,要么全无,这意味着我必须按原样使用所有提供的定义,要么我必须创建/定义整个类的模板专业化。

我正在编写一些测试代码,以更好地理解编写自定义分配器。 我想提供分配器的自定义定义::分配()。 我必须转发声明分配器吗? 还是我的 allocate() 原型错误? 还是我必须为分配器提供模板专用化,以便我可以提供我自己的 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。 我查看了头文件"bits/allocator.h"(包含在定义类分配器的"内存"中。 没有看到方法分配()。 方法原型是否在基类之一中?

这是因为在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 d 为 __gnu_cxx::new_allocator ,您可以使用这些知识来专门化您的函数(请注意,它必须与原始模板位于同一命名空间中 - 根据专用化规则):

namespace __gnu_cxx {
    template <>
    new_allocator<int>::pointer
    new_allocator<int>::allocate(
        new_allocator<int>::size_type n,
        std::allocator<void>::const_pointer hint)
    {
        std::cout << "Doing an alloc for an int allocator" << std::endl;
        return nullptr;
    }
}

我真的不能强调不这样做。但追踪很有趣。

查看 MinGW g++4.9 附带的 libstdc++ 标头,allocate 成员函数的定义存在于标头ext/new_allocator.h中定义的类new_allocator中。 std::allocator公开继承自new_allocator.

如果libstdc++选择将allocate定义为std::allocator本身的成员函数,您的代码就会编译(它在VS2013上编译,因为std::allocator的实现确实定义了allocate成员函数),但即便如此,它仍然是未定义的行为。

来自 N3337, §17.6.4.2.1/2[命名空间.std]

如果C++程序
声明     — 标准库类模板的任何成员函数的显式专用化,或
...

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