使用类型特征的部分类专用化
Partial class specialization using type traits
我对C++很陌生,我遇到了一个问题,我似乎无法解决或找到有相同问题的其他人。
我有一个定义的类Polynomial
:
template<class C>
class Polynomial {
std::vector<C> coefficients;
...
public:
...
const double integral(double, double);
...
};
我需要确保,如果C
是整型类型,则不能调用integral()
方法。显然,这意味着使用类型特征,但是我已经尝试在方法本身上使用template<typename = typename std::enable_if<!std::is_integral<C>::value, C>::type>
,尽管它可以编译,但现在我无法制作具有整型作为模板参数的对象。
然后我想,应该可以创建Polynomial
类的部分特化,即具有浮点的类的专用化,一个具有积分,一个具有复数。类似的东西
template<typename C>
class Polynomial<typename std::enable_if<std::is_floating_point<C>::value, C>::type> : Polynomial<C> {
public:
const double integral(double, double);
};
然而,无论我怎么做,它似乎永远不会奏效。
我想我的问题是:如何使用类型特征作为专用化来指定类的部分专用化?
希望你能帮上忙。
你需要一个单独的基类来存储常见的东西,然后你可以像这样为Polynomial
做模板专用化:
template<class C>
class PolynomialBase {
std::vector<C> coefficients;
};
template <typename T, typename Enable = void>
class Polynomial;
template<typename C>
class Polynomial<C, typename std::enable_if<!std::is_integral<C>::value>::type> : PolynomialBase<C> {
public:
const double integral(double, double);
};
template<typename C>
class Polynomial<C, typename std::enable_if<std::is_integral<C>::value>::type> : PolynomialBase<C> {};
玩得太晚了?
显然,您可以通过专业化来解决问题,而 krisz 的答案展示了一种可能的方法。
但是您可以通过SFINAE简单地启用/禁用integral()
来解决它。
您无法检查C
类型,因为 SFINAE 适用于特定于该方法的模板,而不是类的模板,因此您必须integral()
模板方法。
通过示例
template <typename D = C>
std::enable_if_t<std::is_floating_point<D>::value, double>
integral (double, double)
{ return 1.0; }
这样,您可以检查默认为C
类型的D
类型。
以下是完整的编译示例
#include <vector>
#include <type_traits>
template <typename C>
class Polynomial
{
private:
std::vector<C> coefficients;
public:
template <typename D = C>
std::enable_if_t<std::is_floating_point<D>::value, double>
integral (double, double)
{ return 1.0; }
};
int main()
{
Polynomial<float> pf;
Polynomial<int> pi;
pf.integral(0.0, 0.0); // compile
// pi.integral(0.0, 0.0); // compilation error
}
此解决方案的问题是,如果您显式D
类型,可能会被"劫持">
Polynomial<int> pi;
// pi.integral(0.0, 0.0); // compilation error
pi.integral<double>(0.0, 0.0); // hijacked: compile
为避免劫持问题,您可以修改SFINAE测试,以integral()
强加C
和D
是同一类型
所以如果你这样写
template <typename D = C>
std::enable_if_t<std::is_floating_point<D>::value
&& std::is_same<C, D>::value, double>
integral (double, double)
{ return 1.0; }
integral()
不能再被劫持
Polynomial<int> pi;
// pi.integral(0.0, 0.0); // compilation error
// pi.integral<double>(0.0, 0.0); // compilation error
相关文章:
- .cpp和.h文件中的模板专用化声明
- 调用专用模板时出错"no matching function for call to [...]"
- 模板专用化(按容器):value_type
- 静态数据成员模板专用化的实例化点在哪里
- 特征 3 类的模板专用化
- Visual Studio 2017 不允许我创建 C++ 专用模板
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 具有常量引用参数的函数模板专用化
- 使用其他模板的模板专用化
- 为我的 c++ 类介绍制作一个三角形分类器.我有几个问题
- 使用专用显卡进行 OpenGL 渲染时帧速率较低
- 嵌套模板显式专用化
- 更改 C++ 中的组合分类变量
- 使用类型特征的部分类专用化
- 将 CRTP 与部分类专用化结合使用?
- 针对多种类型的部分类模板专用化
- 参数包不在最后位置的部分类模板专用化
- 具有多个参数的部分类模板专用化
- 函数指针类型和值的部分类专用化
- 带有映射的部分类模板专用化