rub*_*ict 18 c++ gcc templates
我在使用GCC编译以下程序时遇到问题(我尝试了很多版本,都失败并出现相同的错误).它在Clang编译得很好:
#include <vector>
struct Tag1
{
    static void logAllocation(){}
    static void logDeallocation(){}
};
struct Tag2
{
    static void logAllocation(){}
    static void logDeallocation(){}
};
template<typename Tag, typename T>
struct MyAllocator
{
    using value_type = typename std::allocator<T>::value_type;
    T* allocate(std::size_t n)
    {
        Tag::logAllocation();
        return std::allocator<T>{}.allocate(n);
    }
    void deallocate(T* p, std::size_t n)
    {
        Tag::logDeallocation();
        std::allocator<T>{}.deallocate(p, n);
    }
};
int main()
{
    std::vector<int, MyAllocator<Tag1, int>> vec;
}
问题是GCC认为在Tag==int内部MyAllocator,我得到一个错误,'logDeallocation'不是'int'的成员.这是GCC中的错误吗?当我翻转模板参数(template<typename T, typename Tag)并std::vector<int, MyAllocator<int, Tag1>> vec;在编译时声明我的矢量.
T.C*_*.C. 21
这不是一个符合标准的分配器,并将其作为一个提供给库组件会导致未定义的行为(因此,两个实现都符合).您缺少!=,==跨类型隐式转换,以及相关的,rebind.
allocator_traits默认rebind实现假定值类型是第一个模板参数(并且任何剩余的模板参数都可以不经修改地重用).由于分配器不是这种情况,您需要提供自己的分配器rebind或反转模板参数顺序.
vector非常特别的是,如果需要,实现可以简单地使用提供的分配器而不重新绑定.这就是你的示例代码用libc ++编译的原因.libstdc ++的容器支持允许您执行的扩展vector<int, allocator<char>>,因此它始终将分配器重新绑定到指定的value_type.