模板参数无效;不能出现在常量表达式中

Posted

技术标签:

【中文标题】模板参数无效;不能出现在常量表达式中【英文标题】:Template argument invalid; cannot appear in constant expression 【发布时间】:2014-05-21 20:35:37 【问题描述】:

在我的程序中,我使用的是自制的FFT。为了提高性能,我尝试在编译时使用模板计算复杂因素。产生错误的代码部分是

typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;

void fft(CArray& x)
    const size_t N = x.size();
    if(N==1)return;

    CArray even = x[std::slice(0,N/2,2)];
    CArray odd = x[std::slice(1,N/2,2)];

    fft(even);
    fft(odd);

    for(size_t k=0; k<N/2; k++)
        Complex t = Twiddle<N,k>::value() * odd[k];
        x[k] = even[k] + t;
        x[k+N/2] = even[k] - t;
    

Twiddle&lt; N,k&gt; 在哪里

template <size_t N, size_t k, typename T=std::complex<double> >
struct Twiddle;

template <size_t N, size_t k>
struct Twiddle<N,k,std::complex<double> >
    static std::complex<double> value()
        return std::complex<double>(Cos<N,k>::value(),Sin<N,k>::value());
    
;

CosSin 以类似的方式进行模板化,它们使用递归来获取它们的值。他们工作得很好。但是,当我尝试编译代码时,FFT 部分会产生错误。错误的确切措辞是:

'N' 不能出现在常量表达式中 “k”不能出现在常量表达式中 模板参数 1 无效 模板参数 2 无效

任何帮助将不胜感激。

【问题讨论】:

好吧,正如它所说,N 不是编译时常量表达式,因为它是从x.size() 动态获得的。模板类是类型,必须在编译类型时确定。 有什么办法解决这个问题吗?我是否可以在头文件中调用我需要的值,例如 Twiddle、Twiddle 等? 【参考方案1】:

根据 C++ 标准(第 14.3.2 节模板非类型参数)

1 非类型、非模板模板参数的模板参数 应为以下之一: — 对于积分的非类型模板参数或 枚举类型,转换后的常量表达式 (5.19) 模板参数的类型;

【讨论】:

有什么方法可以创建一个包含我将使用的所有值的表,比如一个包含所有整数参数的文件? @CJ13 我认为你应该选择另一种方法。

以上是关于模板参数无效;不能出现在常量表达式中的主要内容,如果未能解决你的问题,请参考以下文章

常量表达式包含无效操作 - 不突出显示其他变量?

无效的常量表达式比特广播

为啥指向函数的“const”指针不能在常量表达式中使用?

intel fortran 编译错误“此内在函数在常量表达式中无效”

Chapter16:模板

反思 - Java 8 - 无效的常量类型