我对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;
};
add
和get
的通用实现都是正确的,但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
?为什么他们不从泛型类继承?
答案 0 :(得分:4)
非常确定您的问题是您需要使用_arrays
来限定名称this
。尝试将_arrays
的所有实例更改为this->_arrays
。
在C ++中,为了访问模板基类的成员,你必须进一步限定名称,以澄清名称是否依赖于基类的模板参数(我认为)。如果您对此功能的更多技术细节感兴趣(比我更好地解释),请查看here。
答案 1 :(得分:0)
<强>注释强>
您可以考虑标记调度:
#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实际上正在回答您的问题。