1
我有以下的非多容器的容器简单的情况下工作:复制从多容器内容到一个容器
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'函数用于处理container-in-container-in-container的情况(无论事实上嵌套得多深,都必须工作)。我在第一稿中使用vector作为SingleContainer(我会尽量在后面概括)。顺便说一句,我得到is_container的代码在计算器Determine if a type is an STL container at compile time以前的线程,所以我们可以只取一部分是理所当然的:
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”函数的前向声明不是必需的,但我可以看到你想要提及它。 – prestokeys 2014-11-03 23:03:45
我还在学习,所以谢谢你的提示。 – 2014-11-04 13:31:11
你必须意味着你仍然在学习C++语言本身(在你认识的其他语言中)。因为你的解决方案背后的逻辑可能是独立于语言的,所以它是高级的思维,我从来没有想过。 – prestokeys 2014-11-04 15:51:56