C++模板-在模板中评估静态内联方法,并将结果作为模板类型参数传递
我有一个接受类F和int X的模板。类F有一个静态内联双值X方法。根据eval返回的结果,我需要在int类型和long类型之间进行选择——尽可能小的类型将适合转换为整数的结果,因为它是双精度的 我试着这样做,但我得到的非类型模板参数不是常量表达式错误 有没有办法创建这样的模板 ============================ 更新: 根据建议,我在eval函数中添加了constexpr。它现在起作用了,但现在总是这样。完整示例:C++模板-在模板中评估静态内联方法,并将结果作为模板类型参数传递,c++,templates,C++,Templates,我有一个接受类F和int X的模板。类F有一个静态内联双值X方法。根据eval返回的结果,我需要在int类型和long类型之间进行选择——尽可能小的类型将适合转换为整数的结果,因为它是双精度的 我试着这样做,但我得到的非类型模板参数不是常量表达式错误 有没有办法创建这样的模板 ============================ 更新: 根据建议,我在eval函数中添加了constexpr。它现在起作用了,但现在总是这样。完整示例: #include <iostream> #in
#include <iostream>
#include <math.h>
#include <typeinfo>
struct X {
static constexpr double eval(double x) { return x; };
};
template<class L, class R>
struct MULT {
static constexpr double eval(double x) {
return L::eval(x) * R::eval(x);
}
};
template<class L, class R>
struct DIV {
static constexpr double eval(double x) {
return L::eval(x) / R::eval(x);
}
};
template <bool is_int>
struct SELECT {
typedef long type;
};
template <>
struct SELECT<true> {
typedef int type;
};
template<class F, int X>
struct DEDUCTOR {
typedef typename SELECT<-32768 < F::eval(X) && F::eval(X) < 32767>::type result;
};
int main() {
// typedef MULT<MULT<X, X>, X> F; // works
typedef DIV<DIV<X, X>, X> F; // doesn't work
typedef DEDUCTOR<F, 0> deductor;
std::cout << typeid(deductor::result).name() << std::endl;
return 0;
}
您的主要问题是这一行:
typedef SELECT<-32768 < F::eval(X) && F::eval(X) < 32767> result;
应该是:
typedef typename SELECT < -32768 < F::eval(X) && F::eval(X) < 32767 > ::type result;
注意:trailing::type实际引用SELECT结构中的类型,并引导typename,因为它是依赖类型
下面是一个工作版本。注意,我也稍微更改了SELECT,但编译时不需要这样做
template <bool is_int>
struct SELECT {
typedef long type;
};
template <>
struct SELECT<true> {
typedef int type;
};
template <class F, int X>
struct DEDUCTOR {
typedef typename SELECT < -32768 < F::eval(X) && F::eval(X) < 32767 > ::type result;
};
struct myS
{
static constexpr double eval(double x) { return x; }
};
int main()
{
std::cout << typeid(DEDUCTOR<myS, 100>::result).name() << std::endl;
std::cout << typeid(DEDUCTOR<myS, 100000>::result).name() << std::endl;
}
除非eval是一个constexpr函数,可以在编译时进行计算。因为这是模板被实例化的时候。@SamVarshavchik我尝试在函数前面添加“constexpr”,因为它是编译时计算的,但它仍然显示相同的错误。请发布一个。这意味着函数不是常量函数,因此不能在模板参数中使用。C++根本不这样工作。我尝试静态CONTXPR双Valuxx{Read 0;},并且我没有错误。你能看看这个吗?或我猜您的eval函数不可能在编译时计算。在这种情况下,eval不能是constexpr。更新后,您将被零除。将其更改为1,它就会工作。[看这里]啊,是的,我选择了一个错误的例子:D谢谢你,不管怎样,我设法找出最后一个问题是eval的另一个实现,它使用了pow函数。我需要自己去实现它。非常感谢,你帮了我很多!
typedef typename SELECT < -32768 < F::eval(X) && F::eval(X) < 32767 > ::type result;
template <bool is_int>
struct SELECT {
typedef long type;
};
template <>
struct SELECT<true> {
typedef int type;
};
template <class F, int X>
struct DEDUCTOR {
typedef typename SELECT < -32768 < F::eval(X) && F::eval(X) < 32767 > ::type result;
};
struct myS
{
static constexpr double eval(double x) { return x; }
};
int main()
{
std::cout << typeid(DEDUCTOR<myS, 100>::result).name() << std::endl;
std::cout << typeid(DEDUCTOR<myS, 100000>::result).name() << std::endl;
}