C ++ - 通过模板化仿函数专门化成员函数模板不能编译

时间:2013-03-26 22:33:41

标签: c++ templates type-conversion template-specialization

我希望创建一个可以在浮点数和多重数组之间进行转换的类。也就是说,相关的实例(由<double><float>参数化)以及传递float*double*的决定是在运行时决定的,而不是静态的。

作为另一个问题的proposed answer,但是根据this answer进行了修改(因为我知道不可能完全专门化类中的成员函数模板),纯虚基类{{1提供简单重载的成员函数的子类被定义为定义BaseDest。我使用这个基类来维护DestImpl<T>个实例的动态集合,具有不同的DestImpl<T>。此类提供T成员函数的显式重载;一个用于assign(),另一个用于double *。我们的想法是,在运行时,float *通过多态指针或引用调用,然后调用BaseDest::assign()中正确的虚拟assign()成员函数。

现在,重要的是数组的非指针类型与DestImpl<T>中的T匹配,调用DestImpl<T>函数(可能是memcpy),并且当类型不匹配时执行较慢的静态逐项逐项复制。因此fast_copy()成员函数会将其卸载到模板化的仿函数。这个仿函数有两个特殊化 - 一个是仿函数的类型参数与assign()的类型相匹配(因此调用快速拷贝),另一个是捕获所有其他情况(并调用慢速)拷贝)。

但是,我无法获得以下代码进行编译。注释显示编译器错误和警告出现的位置 - 我怀疑它们是相关的。我不明白为什么DestImpl<T>的第二个专业化无法实例化为apply_helper

apply_helper<double>

编辑:这里似乎有用 - 将class BaseDest { public: virtual ~BaseDest() {} virtual void assign(const double * v, size_t cnt) = 0; virtual void assign(const float * v, size_t cnt) = 0; }; template <typename T> class DestImpl : public BaseDest { public: void assign(const double * v, size_t cnt) { assign_helper<T>()(v, cnt); } void assign(const float * v, size_t cnt) { assign_helper<T>()(v, cnt); // ERROR: no matching function for call to object of type 'assign_helper<double>' } protected: template <typename U> struct assign_helper { void operator()(const U * v, size_t cnt) { for (size_t i = 0; i < cnt; ++i) { //slow_copy(v[i]); } } }; template <typename U> struct assign_helper<T> { // WARNING: Class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used void operator()(const T * v, size_t cnt) { //fast_copy(v, cnt); } }; }; void test() { DestImpl<double> d; // error mentioned above appears when this is present } 结构(现在是一个类)移出assign_helper类定义。我不确定这是否是正确的方法,但到目前为止似乎确实有效:

DestImpl<T>

1 个答案:

答案 0 :(得分:0)

template <typename U>
  struct assign_helper<T> {  // WARNING: Class template partial specialization contains a template parameter that can not be deduced; this partial specialization will never be used

以上是导致错误的原因。警告明确告诉您永远不会使用此定义。您想要的是template < typename U >而不是template <>