簡體   English   中英

使用 Lambda 解包可變參數 Arguments 時增加指針

[英]Increment pointer when Unpacking Variadic Arguments with Lambda

我有以下代碼,它有一個 function VariadicWrite並且這個 function 接受一個指針,它可以通過將其遞增到它來修改它指向不同的 ZCD69B4957F06CD818D7BF3D61980E2 的位置,具體取決於寫入它的位置:

#include <iostream>
#include <cstring>

template<typename T>
T Read(void* &ptr) noexcept
{
    T result;
    memcpy(&result, ptr, sizeof(result));
    ptr = static_cast<T*>(ptr) + 1;
    return result;
}

template<typename T>
void Write(void* &ptr, T result) noexcept
{
    memcpy(ptr, &result, sizeof(result));
    ptr = static_cast<T*>(ptr) + 1;
}

template<typename... Args>
auto VariadicWrite(void*& ptr, Args&&... args)
{
    (Write(ptr, args), ...); //unpack Args
    return 0;
}

int main()
{
    void* ptr = malloc(1024);
    memset(ptr, 0, 1024);
    void* temp = ptr;

    VariadicWrite(ptr, 1, 2, 3);
    
    std::cout<<Read<int>(ptr)<<"\n";
    std::cout<<Read<int>(ptr)<<"\n";
    std::cout<<Read<int>(ptr)<<"\n";

    free(temp);
    return 0;
}

這里的問題是代碼打印出0, 0, 0, 0如果我使用: void*& ptr 如果我做void* ptr它會打印出0, 1, 2, 3ptr指針永遠不會增加。

如何修改VariadicWriteptr指針? 我認為void*&會起作用,但在這種情況下它不會:S

問題是您的VariadicWrite()調用將修改ptr以指向您寫入數據的末尾。 然后您調用Read()而不將指針重置回起點,因此您從已寫入數據之后的緩沖區的未初始化部分讀取零。

插入ptr = temp; 在寫入和讀取之間,看看是否可以解決它。

void* ptr不起作用的原因是每次調用Write(ptr, ...)都會增加Write() function 的 scope 中參數的本地副本。 VariadicWrite()中的變量ptr在調用Write()后不會更改,因此下一次調用將使用相同的值。

如果您更改為VariadicWrite(void* ptr, …)Write(void*& ptr, …) ,您可能會得到您想要的行為。 但我建議這是一個壞主意。

正如我們從您的示例中的錯誤中看到的那樣,了解 function 是否會修改傳遞引用參數至關重要,但從使用 function 的代碼中卻不明顯。 這往往會招致錯誤,就像您在此處創建的錯誤一樣。 一個不一致的接口,其中VariadicWrite()不會修改其參數,但Write()會修改,只會使避免這種錯誤變得更加困難。

通常,最好避免非常量引用,因為它們通常會導致這樣的錯誤。 我建議返回新指針而不是修改參數。

template<typename T>
void* Write(void* ptr, const T& arg)
{ 
    return static_cast<T*>(ptr) + 1;
}

template<typename... Args>
void* WriteV(void* ptr, Args&&... args)
{
    ((ptr = Write(ptr, args)), ...);
    return ptr;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM