我是C ++的新手,我遇到了一个似乎无法解决的问题,或者找到了遇到同样问题的其他人。
我定义了一个类Polynomial
:
template<class C>
class Polynomial {
std::vector<C> coefficients;
...
public:
...
const double integral(double, double);
...
};
我需要确保,如果integral()
是一个整数类型,则无法调用C
方法。显然这意味着使用类型特征,但是我已经尝试在方法本身上使用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);
};
但是,无论我怎么做,它似乎永远不会起作用。
我想我的问题是:如何使用类型特征作为特化来指定类的部分特化?
我希望你能提供帮助。
答案 0 :(得分:3)
您需要为常见内容提供单独的基类,然后您可以像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> {};
创建模板专业化:
CREATE TABLE AS SELECT
答案 1 :(得分:3)
玩的已经太晚了?
显然,你可以通过专业化解决问题,而克里斯的答案显示出一种可能的方式。但您可以通过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; }
这样您就可以检查D
类型默认的C
类型。
以下是完整的编译示例
#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
}
这个解决方案的问题是可以被劫持&#34;如果您明确D
类型
Polynomial<int> pi;
// pi.integral(0.0, 0.0); // compilation error
pi.integral<double>(0.0, 0.0); // hijacked: compile
为避免劫持问题,您可以修改integral()
的SFINAE测试,同时强调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