通过模板化的函函数特化成员函数模板无法编译
C++ - specialising member function template via templated functor does not compile
我希望创建一个类,可以在浮点数和双精度数组之间进行多态转换。也就是说,相关的实例(由<double>
或<float>
参数化)和传递float*
或double*
的决定是在运行时决定的,而不是静态的。
作为对另一个问题的建议答案,但根据这个答案进行修改(因为我理解在类内部完全专门化成员函数模板是不可能的),提供简单重载成员函数的纯虚拟基类BaseDest
被子类化为定义DestImpl<T>
。我使用这个基类来维护DestImpl<T>
实例的动态集合,其中T
是不同的。该类提供assign()
成员函数的显式重载;一个用于double *
,另一个用于float *
。其思想是,在运行时,BaseDest::assign()
通过多态指针或引用调用,这反过来调用DestImpl<T>
中正确的虚拟assign()
成员函数。
现在,重要的是数组的非指针类型匹配DestImpl<T>
中的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);
}
};
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 <>
- 将重载的成员函数传递给函数模板
- 解决模板成员函数重载
- 没有公共构造函数作为另一个类模板成员的类模板
- 是否可以获取成员函数模板参数的拥有对象?
- GCC 7 中模板类的模板成员函数的专用化
- 函数模板签名中忽略的成员类型def 的访问说明符
- 实例化多种类型的成员函数模板
- C++:递归成员函数模板
- 专用于可变参数模板成员函数
- MSVC 2017 - 错误 - 如何将模板类 X 的模板成员函数声明为嵌套类 X::Y 的好友
- 将函数和成员函数传递给模板方法
- 类模板成员函数的专用化
- 类成员函数的函数模板专用化
- 使用模板参数还包括 constexpr 成员函数enable_if单独定义和声明模板成员函数
- 如何通过指针将模板成员函数传递给另一个成员函数
- std::绑定可变参数模板成员函数和通用引用
- C++成员函数模板将成员函数指针作为模板参数
- 使用模板成员函数时出现LNK2001错误
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- 使用类的静态函数模板成员的链接器错误