c++ - 为什么 GCC 认为模板参数是 int 而它是完全不同的类型?

标签 c++ templates gcc

我在使用 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 )并将我的 vector 声明为 std::vector<int, MyAllocator<int, Tag1>> vec;它编译。<​​/p>

最佳答案

这不是一个符合要求的分配器,将它作为一个分配器提供给库组件会导致未定义的行为(因此,两个实现都是符合要求的)。你不见了!= , == ,跨类型隐式转换,以及与此处相关的 rebind .

allocator_traits的默认值 rebind实现假定值类型是第一个模板参数(并且任何剩余的模板参数都可以不加修改地重用)。由于您的分配器并非如此,因此您需要提供自己的 rebind或反转模板参数顺序。


vector非常特别的是,如果需要,实现可以简单地按原样使用提供的分配器而无需重新绑定(bind)。这就是您的示例代码使用 libc++ 编译的原因。 libstdc++ 的容器支持允许您执行 vector<int, allocator<char>> 的扩展,所以它总是将分配器重新绑定(bind)到指定的 value_type .

关于c++ - 为什么 GCC 认为模板参数是 int 而它是完全不同的类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48978576/

相关文章:

c++如何使用两个迭代器从 vector 复制范围

c++ - 抛出可由 C++98 和 C++1x 编译的析构函数。有没有更好的办法?

c++ - BSTR 中是否有 Unicode 符号?

c++ - 不同命名空间中模板的特化

c++ - double /整数模板函数的 vector

c++ - C++中的模板成员函数

linux - 如何在 RHEL 7.4 上安装 gcc 4.9.2

C++:为什么构造函数 "A(A a) {}"是非法的?

c++ - 为什么 GCC 聚合初始化数组首先用零填充整个事物,包括非零元素?

c 二进制文件大于源文件