[英]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, 3
但ptr
指針永遠不會增加。
如何修改VariadicWrite
的ptr
指針? 我認為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.