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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.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_Recursion - Fatal编程技术网

C++ 在处理递归错误时非法使用显式模板参数

C++ 在处理递归错误时非法使用显式模板参数,c++,templates,recursion,C++,Templates,Recursion,我试图实现SHA256哈希函数,以便在具有编译时功能的程序中使用。预处理的一个步骤是根据公式填充消息/输入数据。填充量自然必须为正整数。该算法依赖于块处理,每个块只能容纳如此多的数据,因此如果数据大于一个块,我们需要更多的块。我使用递归解决了这个问题,但这抛出了C1202-模板定义是递归的或超出了复杂性限制 template <uint32_t DataLength, uint32_t ChunkSize, uint32_t Chunks> int GetBitsToAppend()

我试图实现SHA256哈希函数,以便在具有编译时功能的程序中使用。预处理的一个步骤是根据公式填充消息/输入数据。填充量自然必须为正整数。该算法依赖于块处理,每个块只能容纳如此多的数据,因此如果数据大于一个块,我们需要更多的块。我使用递归解决了这个问题,但这抛出了C1202-模板定义是递归的或超出了复杂性限制

template <uint32_t DataLength, uint32_t ChunkSize, uint32_t Chunks>
int GetBitsToAppend() {
    static int BitsToAppend = ChunkSize*Chunks - DataLength - 1 - (ChunkSize / 8);
    return 0 > BitsToAppend ? GetBitsToAppend<DataLength, ChunkSize, Chunks+1>() : BitsToAppend;
}
模板
int GetBitsToAppend(){
静态int-BitsToAppend=ChunkSize*Chunks-DataLength-1-(ChunkSize/8);
返回0>BitsToAppend?GetBitsToAppend():BitsToAppend;
}
我试图通过添加一个显式的模板定义来解决这个问题,但是这会引发一个新的错误;C2768,显式模板参数的非法使用。代码如下:

template<uint32_t DataLength, uint32_t ChunkSize>
int GetBitsToAppend<DataLength, ChunkSize, 1024>() {
    int BitsToAppend = ChunkSize*Chunks - DataLength - 1 (ChunkSize / 8)
}
模板
int GetBitsToAppend(){
int BitsToAppend=ChunkSize*Chunks-DataLength-1(ChunkSize/8)
}
如果我使用一个普通的循环函数,它会像预期的那样工作,但是由于需要在编译时知道处理数组的长度,这会中断。e、 g:

int GetBitsToAppend(uint32_t DataLength, uint32_t ChunkSize, uint32_t Chunks) {
    static int BitsToAppend = ChunkSize * Chunks - DataLength - 1 - (ChunkSize>>3);
    return 0 > BitsToAppend ? GetBitsToAppend(DataLength, ChunkSize, Chunks+1) : BitsToAppend;
}

template <typename T, size_t OutputSize, size_t ByteSizeInput, size_t Rounds, size_t ChunkSize>
std::bitset<OutputSize> SHA(const T data) {

    // Pre-processing
    const uint32_t DataLength = ByteSizeInput << 3;
    const uint32_t BitsToAppend = GetBitsToAppend(DataLength, ChunkSize, 1); // Run-time calculation

    const uint32_t TargetSize = (DataLength + BitsToAppend + (ChunkSize>>3) + 1) / sizeof(uint32_t);
    std::array<uint32_t, TargetSize> ProcessArray; // Invalid template argument.
    
    // Copy data into ProcessArray and perform remaining preprocessing
//........
int GetBitsToAppend(uint32\u t数据长度、uint32\u t块大小、uint32\u t块){
静态int-BitsToAppend=ChunkSize*Chunks-DataLength-1-(ChunkSize>>3);
返回0>BitsToAppend?GetBitsToAppend(DataLength,ChunkSize,Chunks+1):BitsToAppend;
}
模板
std::位集SHA(常量数据){
//预处理
const uint32_t数据长度=字节输入>3)+1)/sizeof(uint32_t);
std::array PROCESSARY;//模板参数无效。
//将数据复制到ProcessArray并执行剩余的预处理
//........
ChunkSize是常量,由函数的模板参数给出,ByteSizeInput也是常量。ChunkSize>>3表示在预处理中追加的整数的大小,在SHA256/224中为64位,在SHA384/512.Aka中为128位。相应的块大小除以8


有人知道如何解决这个问题吗?

在C++17及更高版本中,可以使用
if constexpr来解决这个问题,如下所示:

template <uint32_t DataLength, uint32_t ChunkSize, uint32_t Chunks>
int GetBitsToAppend() {
    constexpr int BitsToAppend = ChunkSize*Chunks - DataLength - 1 - (ChunkSize / 8);
    if constexpr (0 > BitsToAppend)
        return GetBitsToAppend<DataLength, ChunkSize, Chunks+1>();
    else
        return BitsToAppend;
}
模板
int GetBitsToAppend(){
constexpr int BitsToAppend=ChunkSize*Chunks-DataLength-1-(ChunkSize/8);
if constexpr(0>BitsToAppend)
返回GetBitsToAppend();
其他的
返回BitsToAppend;
}

除了桑德斯先生善意的回答之外:

编译器不理解(以我的经验)工作模板在简单地分配给变量时计算为constepr,从而导致一些进一步的错误。将
constepxr
添加到
GetBitsToAppend
的函数签名以及
BitsToAppend
和sum变量
TargetSize
可提供所需的结果:

template <uint32_t DataLength, uint32_t ChunkSize, uint32_t Chunks>
constexpr int GetBitsToAppend() {
    constexpr int BitsToAppend = ChunkSize * Chunks - DataLength - 1 - (ChunkSize/8);
    #pragma warning(suppress:4984) //Remove compatibility warning
    if constexpr (0 > BitsToAppend)
         return GetBitsToAppend<DataLength, ChunkSize, (Chunks+1)>();
    else
        return BitsToAppend;
}

template <typename T, size_t OutputSize, size_t ByteSizeInput, size_t Rounds, size_t ChunkSize>
std::bitset<OutputSize> SHA(const T data) {
    //Pre-processing
    constexpr uint32_t DataLength = ByteSizeInput << 3;
    constexpr uint32_t BitsToAppend = GetBitsToAppend<DataLength, ChunkSize, 1>();
    
    constexpr uint32_t TargetSize = (DataLength + BitsToAppend + (ChunkSize>>3)+1) / sizeof(uint32_t)
    std::array<uint32_t, TargetSize> ProcessArray; // Compiles!
//...
模板
constexpr int GetBitsToAppend(){
constexpr int BitsToAppend=ChunkSize*Chunks-DataLength-1-(ChunkSize/8);
#pragma警告(抑制:4984)//删除兼容性警告
if constexpr(0>BitsToAppend)
返回GetBitsToAppend();
其他的
返回BitsToAppend;
}
模板
std::位集SHA(常量数据){
//预处理
constexpr uint32_t数据长度=字节输入>3)+1)/sizeof(uint32_t)
std::array ProcessArray;//编译!
//...

谢谢!这解决了递归问题。您是否也知道为什么它的计算结果不是constepxr?它似乎没有任何歧义,但我不是专家。GetBitsToAppend中的所有计算都是常量或在编译时确定的?如果这是一个愚蠢的问题,请原谅。我找到了一个解决方案ion,请参阅下面我的答案。此代码中使用的标题:
用于uint32、大小等,
用于std::array和
用于std::bitset