我想创建一个类,它可以和双精度浮点数的多态阵列之间转换。 也就是说,有关实例(由参数化<double>
或<float>
),并传递一个决定float*
或double*
在运行时决定,而不是静态。
作为一个建议的回答另一个问题,但根据修改这个答案 (因为我知道这是不可能完全专注一类中的成员函数模板),一个纯虚基类BaseDest
,提供简单的重载成员函数是子类来限定DestImpl<T>
我用这个基类保持的动态集合DestImpl<T>
情况下,具有不同T
。 此类提供的明确的重载assign()
成员函数; 一个用于double *
,另一个为float *
。 的想法是,在运行时, BaseDest::assign()
通过一个多态指针或引用被调用,并且这反过来调用正确的虚拟assign()
中的成员函数DestImpl<T>
现在,重要的是,然后在阵列的非指针类型匹配T IN DestImpl<T>
即一个fast_copy()
函数被调用(可能是一个的memcpy),并且当类型不匹配较慢的静态cast-项目按项目执行复制操作。 因此, 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);
}
};