合并/连接未知数量的字节数组

问题描述

我可以使用以下函数合并/组合/连接两个数组,但我如何对其进行修改支持未知数量的数组。换句话说,一个可变参数函数 Args...?

char* concat(char* a,size_t a_size,char* b,size_t b_size) {
    char* c = realloc(a,a_size + b_size);
    memcpy(c + a_size,b,b_size);  // dest is after "a" data,source is b with b_size
    free(b);
    return c;
}

解决方法

使用 spanvector,您可以将其写为:

std::vector<std::byte> Concat(std::span<std::byte> a)
{
    return std::vector<std::byte>(a.data(),a.data() + a.size());
}

template<typename... Args>
std::vector<std::byte> Concat(std::span<std::byte> a,Args... args)
{
  auto vec = std::vector<std::byte>(a.data(),a.data() + a.size());
  auto concat = Concat(args...);
  vec.insert(vec.end(),concat.begin(),concat.end());
  
  return vec;
}

请注意,您需要一个符合 C++20 的编译器才能使用 span。支持最新版本的 GCC、Clang 和 MSVC。

,

我不确定这样的事情是否适合您?我认为这也应该适用于 C++11,如果需要,我相信可以适用于 begin CEFWindowParent1.SetFocus; Sleep(200); keybd_event(Ord('K'),0); end; 。它只分配一次内存,然后随后将提供给 std::span 的每个内存块复制到这个已分配的块中,无需任何重新分配。

concat

Output

#include <cassert>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <utility>

template <typename T>
size_t concatSize(T* arr,size_t len) {
    return len;
}

template <typename T,typename... Args>
size_t concatSize(T* arr,size_t len,Args... args) {
    return len + concatSize(args...);
}

template <typename T>
void copyMem(T* res,T* arr,size_t len) {
    memcpy(res,arr,len);
}

template <typename T,typename... Args>
void copyMem(T* res,Args... args) {
    memcpy(res,len);
    copyMem((T*)((char*)res + len),args...);
}

template <typename T,typename... Args>
std::pair<T*,size_t> concat(T* arr,Args... args) {
    static_assert(sizeof... (Args)%2 == 0,"Not even number of arguments!");
    auto size = concatSize(arr,len,args...);
    T* result = (T*)malloc(size);
    copyMem(result,args...);
    return std::make_pair(result,size);
}

int main() {
    {
        char a[] = {'a','b','c'};
        char b[] = {'d','e','f'};
        char c[] = {'g','h','i'};
        auto result = concat(a,sizeof a,b,sizeof b,c,sizeof c);
        //Don't use regular printf %s since it's not a C-string!
        for(int i = 0; i < result.second; ++i) {
            std::printf("%c ",result.first[i]);
        }
        std::printf("\n");
        free(result.first);
    }
    {
        int a[] = {'1','2','3'};
        int b[] = {'4','5','6'};
        int c[] = {'7','8','9'};
        auto result = concat(a,sizeof( a),sizeof( b),sizeof( c));
        char* x = (char*)result.first;
        for(int i = 0; i < result.second; ++i) {
            std::printf("%c ",x[i]);
        }
        std::printf("\n");
        free(result.first);       
    }
}