【问题标题】:Why does GCC think that the template parameter is int whereas it's a completely different type?为什么 GCC 认为模板参数是 int 而它是完全不同的类型?
【发布时间】:2018-02-25 21:18:41
【问题描述】:

我在使用 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==intMyAllocator 中,我收到一个错误,即 'logDeallocation' 不是 'int' 的成员。这是 GCC 中的错误吗?当我翻转模板参数 (template&lt;typename T, typename Tag) 并将我的向量声明为 std::vector&lt;int, MyAllocator&lt;int, Tag1&gt;&gt; vec; 时,它会编译。

【问题讨论】:

  • 适用于 clang。
  • @BaummitAugen - 什么版本? Clang 3.8 emits a similar error.
  • 问题似乎是_Vector_Base::_Tp_alloc_type 解析为MyAllocator&lt;int, int&gt;。这是由 typedef typename __gnu_cxx::__alloc_traits&lt;_Alloc&gt;::template rebind&lt;_Tp&gt;::other _Tp_alloc_type; 定义的。我不是分配器方面的专家,但可能是您的分配器缺少使rebind 按预期工作所需的东西
  • @StoryTeller 我真的不知道我在说什么,宁愿把它留给更熟悉分配器的人
  • template&lt; class U &gt; struct rebind { using other = MyAllocator&lt;Tag, U&gt;; }; 添加到MyAllocator 似乎可以正常工作。

标签: c++ templates gcc


【解决方案1】:

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

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


vector 的特殊之处在于,如果需要,实现可以直接使用提供的分配器,而无需重新绑定。这就是您的示例代码使用 libc++ 编译的原因。 libstdc++ 的容器支持允许您执行vector&lt;int, allocator&lt;char&gt;&gt; 的扩展,因此它总是将分配器重新绑定到指定的value_type

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多