#include // std::back_inserter #include // std::copy #include // std::cout, std::endl #include // EXIT_SUCCESS #include // std::vector // for C++ containers template void concat (CC source_start, CC source_end, C & target) { std::back_insert_iterator target_iterator = std::back_inserter(target); while (source_start != source_end) { target_iterator = std::copy(source_start->cbegin(), source_start->cend(), target_iterator); ++source_start; } } // for C arrays // this works because C arrays are just fixed width and stored as 1d array in memory // so we can reinterpret a 2d array as a 1d array pointing to the individual elements template void concat (T (& source_array)[M][N], T (& target_array)[M*N]) { T * source_array_pointer = reinterpret_cast(source_array); std::copy(source_array_pointer, source_array_pointer + M*N, target_array); } // need a final version to deal with a subrange of an array, should be able to be done // try yourself! int main () { std::vector> source = { {1,2,3}, {4} }; std::vector target; concat(std::begin(source), std::end(source), target); // C arrays cannot be zig zaggy int source2[][3] = { {1, 2, 3}, {4, 5, 6} }; int target2[6]; concat(source2, target2); // can also use `char const *` as a C string const char * source3[][2] = { { "first", "second" }, { "third", "fourth" } }; const char * target3[4]; concat(source3, target3); for (auto v : target) { std::cout << v << std::endl; } for (auto v : target2) { std::cout << v << std::endl; } for (auto v : target3) { std::cout << v << std::endl; } return EXIT_SUCCESS; }