【问题标题】:Why do I need to redeclare methods/members for partial template specialization?为什么我需要重新声明部分模板专业化的方法/成员?
【发布时间】:2017-02-07 02:15:12
【问题描述】:

我对 C++ 模板比较陌生,并试图找出部分模板专业化。我正在使用模板实现几个相关的数据结构:用于概率存在/不存在查询的布隆过滤器(基于位数组)和用于丰富查询的计数布隆过滤器(带有整数数组)。我从下面的类定义开始。

template<typename ElementType, typename CounterType, size_t maxcount>
class filter
{
    public:
        explicit filter(std::vector<size_t> array_sizes);
        void add(ElementType element);
        CounterType get(ElementType element);

    protected:
        std::vector<std::vector<CounterType>> _arrays;
};

addget 的通用实现是正确的,但 get 可以针对基于位数组的 Bloom 过滤器进行优化。如果我只是尝试添加带有签名的方法...

template<typename ElementType>
bool filter<ElementType, bool, 1>::get(ElementType element);

...我从编译器收到以下错误消息。

error: nested name specifier 'filter<ElementType, bool, 1>::'
    for declaration does not refer into a class, class template
    or class template partial specialization

通过阅读,我了解到除非整个类都部分特化,否则单个方法不能部分特化。无论如何,这实际上很方便,因为这让我有机会为(部分)专业课程提供新标签。我将此添加到标题的底部...

template<typename ElementType> class bloomfilter : public filter<ElementType, bool, 1> {};
template<typename ElementType> class countfilter : public filter<ElementType, uint8_t, 255> {};
template<typename ElementType> class bigcountfilter : public filter<ElementType, uint32_t, 8589934591> {};

...并将方法签名从...更改为...

template<typename ElementType>
bool filter<ElementType, bool, 1>::get(ElementType element);

...到...

template<typename ElementType>
bool bloomfilter<ElementType>::get(ElementType element);

显然这还不够。我需要在部分特化的类定义中明确定义bloomfilter::get 方法。

template<typename ElementType>
class bloomfilter : public filter<ElementType, bool, 1>
{
    public:
        bool get(ElementType element);
};

但是现在编译器抱怨_arrays 是一个未声明的标识符。直到我添加它才能正确编译。

template<typename ElementType>
class bloomfilter : public filter<ElementType, bool, 1>
{
    public:
        bool get(ElementType element);

    protected:
        std::vector<std::vector<bool>> _arrays;
};

为什么我必须在部分特化的模板类中显式定义get_arrays?为什么它们不是从泛型类继承的?

【问题讨论】:

  • 很难理解你的问题是什么。您的问题中没有任何部分专业化的类模板。
  • @Barry 如果通用模板是&lt;ElementType, CounterType, maxcount&gt;,那么&lt;ElementType, bool, 1&gt; 不是部分模板特化吗?如果我的术语不正确,我很高兴得到纠正。
  • 不,是过滤器模板的实例化。

标签: c++ templates specialization


【解决方案1】:

很确定您的问题是您需要使用this 限定名称_arrays。尝试将_arrays 的所有实例更改为this-&gt;_arrays

在 C++ 中,为了访问模板基类的成员,您必须进一步限定名称,以阐明名称是否依赖于基类的模板参数(我认为)。如果您对此功能的更多技术细节感兴趣(解释得比我好),请查看here

【讨论】:

    【解决方案2】:

    评论

    你可以考虑标签调度:

    #include <iostream>
    #include <vector>
    using size_t = std::size_t;
    
    template<typename ElementType, typename CounterType, size_t maxcount>
    class filter
    {
        private:
        template <typename C, size_t>
        struct Tag {};
    
        using bloom_filter_tag = Tag<bool, 1>;
    
        template <typename Tag>
        CounterType get_dispatch(Tag, ElementType element) {
            std::cout << "generic\n";
            return CounterType{};
        }
    
        CounterType get_dispatch(bloom_filter_tag, ElementType element) {
            std::cout << "bloom filter\n";
            return CounterType{};
        }
    
    
        public:
        CounterType get(ElementType element) {
            return get_dispatch(Tag<CounterType, maxcount>(), element);
        }
    };
    
    
    int main() {
        filter<int, bool, 1> bloom;
        bloom.get(1);
        filter<int, double, 2> generic;
        generic.get(1);
    }
    

    不过,define cindy const 实际上是在回答你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-09
      • 2021-01-01
      相关资源
      最近更新 更多