gpt4 book ai didi

c++ - 如何确定类型是否为 memcpy-save?

转载 作者:行者123 更新时间:2023-12-05 09:34:42 25 4
gpt4 key购买 nike

我与非常喜欢 memcpy 的同事一起工作。我正在移植通常处理简单类型(double)的代码,这些代码可以使用 memcpy 安全地复制,并将其扩展到非平凡类型。我想编写一个简单的复制函数,它根据所讨论的类型做正确的事情:

#include <string.h>
#include <vector>
#include <type_traits>

template<class T>
void fancy_copy(const T* src,
T* dest,
unsigned int size)
{
// here:
if(std::is_trivially_copy_assignable<T>::value)
{
memcpy(dest, src, sizeof(T) * size);
}
else
{
for(unsigned int i = 0; i < size; ++i)
{
dest[i] = src[i];
}
}
}

class Custom
{
private:
int value;
public:
Custom& operator=(const Custom& other)
{
value = other.value + 1;
return *this;
}
};

int main()
{
const unsigned int size = 10;

{
std::vector<int> source(size, 0);
std::vector<int> target(size, 0);

fancy_copy<int>(source.data(), target.data(), size);
}

{
std::vector<Custom> source(size);
std::vector<Custom> target(size);

fancy_copy<Custom>(source.data(), target.data(), size);
}

return 0;
}

我使用 C++ 中内置的 type_traits 来确定要使用的实现。不幸的是,当我使用 g++ (10.2) 用 -Wall 编译代码时,我收到了警告

warning: ‘void* memcpy(void*, const void*, size_t)’ writing to an object of type ‘class Custom’ with no trivial copy-assignment; use copy-assignment or copy-initialization instead [-Wclass-memaccess]

因此,对于我的 Custom 类,memcpy 被错误使用。我需要使用哪种类型特征来选择正确的操作并消除警告?

最佳答案

为此使用的正确类型特征是 std::is_trivially_copyable , 不是 std::is_trivially_copy_assignable .

要修复警告,请使用 if constexpr 而不是 if为了在编译时执行检查并且只生成两个分支之一作为给定类型的无条件逻辑 T .即使由于运行时条件逻辑无法访问格式错误的调用,编译器也会发出警告,因为该调用仍然存在于生成的代码中。

也可以考虑使用 std::copy_n 来自 <algorithm>以简化后备逻辑。

在 godbolt.org 上试试:Demo .

对于 C++11,您可以使用 std::enable_if 选择在编译时使用的实现,类似于 C++17 if constexpr :

template<class T>
typename std::enable_if<std::is_trivially_copyable<T>::value>::type
fancy_copy(const T* src, T* dest, unsigned int size)
{
memcpy(dest, src, sizeof(T) * size);
}

template<class T>
typename std::enable_if<!std::is_trivially_copyable<T>::value>::type
fancy_copy(const T* src, T* dest, unsigned int size)
{
std::copy_n(src, size, dest);
}

在 godbolt.org 上试试:Demo .

但最终,正如其他人所指出的,这个 fancy_copy可能是过早的优化,你最好只使用 std::copy_n其中语义正确,允许编译器执行自己的优化。比较 fancy_copy 之间的二进制文件和 std::copy_n 使用 -O3 时自己看看。它们完全相同。

关于c++ - 如何确定类型是否为 memcpy-save?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66372303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com