1

我希望创建一个可以多态地在浮点数组和双精度数组之间转换的类。也就是说,相关的实例(由<double>or参数化<float>)和通过float*ordouble*的决定是在运行时决定的,而不是静态的。

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

现在,重要的是数组的非指针类型匹配 T in DestImpl<T>fast_copy()调用一个函数(可能是一个 memcpy),并且当类型不匹配一个较慢的静态强制逐项复制时执行。因此,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>类定义。我不确定这是不是正确的方法,但到目前为止它似乎确实有效:

// slow copy between different types
template <typename T, typename U>
class assign_helper {
public:
  void operator()(const U *v, size_t cnt) {
    // slow copy
  }
};

// fast copy between same types
template <typename T>
class assign_helper<T, T> {
public:
  void operator()(const T * v, size_t cnt) {
    // fast copy
  }
};


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:

  virtual void assign(const double * v, size_t cnt) {
    assign_helper<T, double>()(v, cnt);
  }
  virtual void assign(const float * v, size_t cnt) {
    assign_helper<T, float>()(v, cnt);
  }
};
4

1 回答 1

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 <>.

于 2013-03-27T16:48:59.703 回答