Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++模板-在模板中评估静态内联方法,并将结果作为模板类型参数传递_C++_Templates - Fatal编程技术网

C++模板-在模板中评估静态内联方法,并将结果作为模板类型参数传递

C++模板-在模板中评估静态内联方法,并将结果作为模板类型参数传递,c++,templates,C++,Templates,我有一个接受类F和int X的模板。类F有一个静态内联双值X方法。根据eval返回的结果,我需要在int类型和long类型之间进行选择——尽可能小的类型将适合转换为整数的结果,因为它是双精度的 我试着这样做,但我得到的非类型模板参数不是常量表达式错误 有没有办法创建这样的模板 ============================ 更新: 根据建议,我在eval函数中添加了constexpr。它现在起作用了,但现在总是这样。完整示例: #include <iostream> #in

我有一个接受类F和int X的模板。类F有一个静态内联双值X方法。根据eval返回的结果,我需要在int类型和long类型之间进行选择——尽可能小的类型将适合转换为整数的结果,因为它是双精度的

我试着这样做,但我得到的非类型模板参数不是常量表达式错误

有没有办法创建这样的模板

============================ 更新:

根据建议,我在eval函数中添加了constexpr。它现在起作用了,但现在总是这样。完整示例:

#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;
}