将内容从多个容器复制到单个容器中
Copying contents from a multi-container into a single container
对于容器中的非多容器的简单情况,我有以下工作:
template <typename MultiContainer, typename SingleContainer>
void check (const MultiContainer& container, SingleContainer& v) {
if (std::is_same<MultiContainer, typename SingleContainer::value_type>::value)
return;
if (is_container<typename MultiContainer::value_type>::value) {
std::vector<typename MultiContainer::value_type::value_type> a; // Using vector for this first draft.
for (const auto& x : container)
std::copy (x.begin(), x.end(), std::back_inserter(a));
if (std::is_same<typename MultiContainer::value_type::value_type, typename SingleContainer::value_type>::value)
v = a;
// else check<decltype(a), SingleContainer>(a, v); // Won't compile
}
}
template <typename MultiContainer, typename SingleContainer>
SingleContainer extractFromMultiContainer (const MultiContainer& container) {
SingleContainer v;
check<MultiContainer, SingleContainer>(container, v);
return v;
}
int main() {
using Multi = std::list<std::vector<int>>;
const Multi multi = { {1,2,3}, {4,5}, {6,7,8,9} };
// using Multi = std::deque<std::list<std::vector<int>>>;
// const Multi multi = { { {1,2,3}, {4,5}, {6,7,8,9} }, { {10,11}, {12,13}, {14,15,16} } };
const auto v = extractFromMultiContainer<Multi, std::vector<int>>(multi);
for (int x : v) std::cout << x << ' '; // 1 2 3 4 5 6 7 8 9
}
但是,我无法在上面的"check"函数中获得所需的递归行,以处理容器中容器的情况(无论实际嵌套有多深,都必须工作)。在这个初稿中,我使用vector作为SingleContainer(稍后我将尝试对此进行推广)。顺便说一句,我从stackerflow中的前一个线程中获得了is_container的代码。在编译时确定一个类型是否是STL容器,所以我们可以理所当然地认为这一部分:
template<typename T>
struct has_const_iterator {
private:
typedef char yes;
typedef struct { char array[2]; } no;
template<typename C> static yes test(typename C::const_iterator*);
template<typename C> static no test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
typedef T type;
};
template <typename T>
struct has_begin_end {
template<typename C> static char (&f(typename std::enable_if<
std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::begin)),
typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
template<typename C> static char (&f(...))[2];
template<typename C> static char (&g(typename std::enable_if<
std::is_same<decltype(static_cast<typename C::const_iterator (C::*)() const>(&C::end)),
typename C::const_iterator(C::*)() const>::value, void>::type*))[1];
template<typename C> static char (&g(...))[2];
static bool const beg_value = sizeof(f<T>(0)) == 1;
static bool const end_value = sizeof(g<T>(0)) == 1;
};
template<typename T>
struct is_container : std::integral_constant<bool, has_const_iterator<T>::value && has_begin_end<T>::beg_value && has_begin_end<T>::end_value> {};
据我所知,您想要一个通用的flatten
函数。你可以通过首先定义基本的平坦化来做到这一点
template<typename T, bool cont = is_container<typename T::value_type>::value>
struct flattener {
template<typename In, typename Out>
static void flatten(In first, In last, Out res);
};
然后继续对容器进行部分专业化
template<typename T> struct flattener<T, true> {
template<typename In, typename Out>
static void flatten(In first, In last, Out res) {
for (; first != last; ++first)
flattener<typename T::value_type>::flatten(std::begin(*first), std::end(*first), res);
}
};
和非集装箱型
template<typename T> struct flattener<T, false> {
template<typename In, typename Out>
static void flatten(In first, In last, Out res) {
std::copy(first, last, res);
}
};
你现在可以像一样使用它
std::vector<int> v1 = { 1, 2, 3 };
std::vector<int> res1;
flattener<decltype(v1)>::flatten(v1.begin(), v1.end(), std::back_inserter(res1));
std::vector<std::vector<int> > v2 = { {9, 8, 7}, {6, 5, 4}, {1, 2, 3} };
std::vector<int> res2;
flattener<decltype(v2)>::flatten(v2.begin(), v2.end(), std::back_inserter(res2));
std::vector<std::vector<std::vector<int> > > v3 = { { {9, 8}, {7, 6} },
{ {6, 5}, {4, 3} },
{ {1, 2}, {3, 4} } };
std::vector<int> res3;
flattener<decltype(v3)>::flatten(v3.begin(), v3.end(), std::back_inserter(res3));
相关文章:
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 在C++程序中输入的文本文件将不起作用,除非文本被复制和粘贴
- 使用strcpy将char数组的元素复制到另一个数组
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- C++ Windows 驱动程序MSB3030无法复制该文件,因为它找不到
- 复制列表初始化的隐式转换的等级是多少
- QT QOpenGLWidget:如何在不使用数据块复制的情况下修改VBO中的单个顶点值?
- char 数组在上次迭代时复制整个单词而不是单个字母
- 在单个链接列表中实现复制构造函数C
- 为什么为单个赋值操作调用复制构造函数和重载赋值运算符
- SDL2 渲染复制多个纹理与单个表面
- cout 对象是否保持单个实例,即它永远不会被复制
- 将内容从多个容器复制到单个容器中
- 我可以删除boost::multi_array的单个维度而不复制其内容吗
- 如何从图像矢量复制单个图像到临时cv::Mat
- 我可以同时复制单个shared_ptr吗?
- 在不带指针的C-string中复制单个字符
- 为什么不复制由单个shared_ptr组成的类呢?
- 使用std::copy复制单个字符