C++ 将n个字符*复制到另一个字符中

C++ 将n个字符*复制到另一个字符中,c++,copy,C++,Copy,我将一个UUID值从SQL SERVER列(通过QtSQL模块)绑定到一个QUuid对象中。 之后,我必须使用赋值函数将其赋值到内部uuid对象中,该函数以char*作为参数 QUuid将几个char*公开为公共成员,所以我必须用几个char*QUuid的成员构建一个16字节的char* 即复制: char buff0; char buff1; char buff2[2]; char buff3[4]; char buff4[8]; 里面 char final[16]; 我使用memcpy来

我将一个UUID值从SQL SERVER列(通过QtSQL模块)绑定到一个QUuid对象中。 之后,我必须使用赋值函数将其赋值到内部uuid对象中,该函数以char*作为参数

QUuid将几个char*公开为公共成员,所以我必须用几个char*QUuid的成员构建一个16字节的char*

即复制:

char buff0;
char buff1;
char buff2[2];
char buff3[4];
char buff4[8];
里面

char final[16];
我使用memcpy来完成这样的任务:

int accu = 0;    
memcpy(final, &buff0, sizeof(buff0)); 
accu += sizeof(buff1);
memcpy(final+accu, &buff1, sizeof(buff1));
accu += sizeof(buff2);
memcpy(final+accu, buff2, sizeof(buff2));
accu += sizeof(buff3);
memcpy(final+accu, buff3, sizeof(buff3));
accu += sizeof(buff4);
memcpy(final+accu, buff4, sizeof(buff4));
但我发现这种方式并不真正可读和可维护。
我正在寻找一种更优雅的方式来完成这项任务。我所说的优雅是指代码行少和/或算术运算少。

一种选择是使用一个并集,这样您就可以交替使用任一定义。

使用x86汇编

;; FASM/NASM syntax
MOV    esi, final
MOVZX  eax, byte [buf0]
MOVZX  ebx, byte [buf1]
MOVZX  ecx, word [buf2]
MOV    edx, dword [buf3] 
MOV    byte [esi], al
MOV    byte [esi+1], bl
MOV    eax, dword [buf4]
MOV    ebx, dword [buf4+4]
MOV    word [esi+2], cx
MOV    dword [esi+4], edx
MOV    dword [esi+8], eax
MOV    dword [esi+12], ebx
或者假设buf的所有内存都是线性分配的(没有填充),只使用一个memcpy,怎么样

memcpy(final, buf0, 16)

首先,下面是一个C++ 2011解决方案,它创建静态检查的代码>代码()/Cuff>函数:它接受<代码> char < /C> > s和数组> ch> < /Case> s作为参数,并且需要添加“<代码> char < /Calp>s”来填充被传递的第一个数组。当然,可以根据需要移除静态检查。原始版本有一些打字错误和遗漏

#include <algorithm>
#include <iostream>
#include <iterator>

int constexpr size(char const&) { return 1; }
template <int Size>
int constexpr size(char const(&)[Size]) { return Size; }
template <typename T0, typename... T>
int constexpr size(T0 const& arg0, T const&... args) {
    return size(arg0) + size(args...);
}

char* copy_intern(char* to, char c) { *to = c; return ++to; }
template <int Size>
char* copy_intern(char* to, char const (&array)[Size]) {
    return std::copy(array, array + Size, to);
}

template <typename T0, typename... T>
char* copy_intern(char* to, T0 const& arg0, T const&... args) {
    return copy_intern(copy_intern(to, arg0), args...);
}

template <int Total, typename... T>
void copy(char (&to)[Total], T const&... args)
{
    static_assert(Total == size(args...), "wrong argument size");
    copy_intern(to, args...);
}

int main()
{
    char buff0    = 'a';
    char buff1    = 'b';
    char buff2[2] = { 'c', 'd' };
    char buff3[4] = { 'e', 'f', 'g', 'h' };
    char buff4[8] = { 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p' };
    char final[16];

    copy(final, buff0, buff1, buff2, buff3, buff4);
    *std::copy(final, final + 16,
               std::ostreambuf_iterator<char>(std::cout)) = '\n';
}

这是一个C++11 STL版本

char* out = final;
out = std::copy_n(&buff0, 1, out);
out = std::copy_n(&buff1, 1, out);
out = std::copy_n(buff2, 2, out);
out = std::copy_n(buff3, 4, out);
out = std::copy_n(buff4, 8, out);

不要胡思乱想。在你最不经意的时候它会出错,然后祝你调试成功。顺便说一句,这是一个很好的假设:)但是很危险yeah@AdamRosenfield-最初的问题是“什么是最酷的方式……”显然,酷孩子们不会担心这些事情哈哈哈。我真的不明白结束我的问题的愿望,因为这是我今天遇到的一个真正的问题,除了一长串的memcpy之外,我想知道是否没有更好的解决方案。我可以看到两个理由来结束这个问题。1) 你还没有向我们展示你的尝试,暗示你只是想让我们为你写这篇文章。2) 你还没有定义“最优雅”是什么意思。嗯,好的,我明白了,让我编辑我的问题so@John迪柏林:那我的编辑呢?@Guillaume07:已经到一半了。你发布的内容有什么“丑陋”之处?除非你告诉我们,否则我们无法知道你在寻找什么。是的,很好。不幸的是,我在msvc下工作,所以没有可变模板。绝对是最聪明的方法!即使使用上面的模板添加函数,代码仍然没有编译,似乎变量有问题,可能是由于“递归”的结束,目前,我无法尝试代码。当我有机会使用一个像样的编译器时,我会修复它。如果r值引用…buff0和buff1需要作为前缀,则可能需要使用此选项,并且希望选择此选项作为最佳答案,但必须选择
    char* tmp = final;
    tmp = copy_intern(tmp, buff0);
    tmp = copy_intern(tmp, buff1);
    tmp = copy_intern(tmp, buff2);
    tmp = copy_intern(tmp, buff3);
    tmp = copy_intern(tmp, buff4);
char* out = final;
out = std::copy_n(&buff0, 1, out);
out = std::copy_n(&buff1, 1, out);
out = std::copy_n(buff2, 2, out);
out = std::copy_n(buff3, 4, out);
out = std::copy_n(buff4, 8, out);