簡體   English   中英

為什么我需要重新聲明方法/成員以進行部分模板專業化?

[英]Why do I need to redeclare methods/members for partial template specialization?

我對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 為什么他們不從泛型類繼承?

很確定你的問題是你需要用this來限定名字_arrays 嘗試將_arrays所有實例更改this->_arrays

在C ++中,為了訪問模板基類的成員,您必須進一步限定名稱,以澄清名稱是否依賴於基類的模板參數(我認為)。 如果您對此功能的更多技術細節感興趣(比我更好地解釋),請看這里

評論

您可以考慮標簽調度:

#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);
}

但是, 定義cindy const實際上是回答你的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM