gpt4 book ai didi

C++ 递归模板分辨率 : flattening vectors of vectors elegantly

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:22:47 24 4
gpt4 key购买 nike

考虑以下(简单的)C++ 代码,将对象从自定义列表类型传输到 std::vector

template<class A> void transfer(std::vector<A>& target, const custom_list_type& source){
for(const A& elem:source){
target.push_back(elem);
}
}

现在,想象一下有一个这样的自定义列表的 std::vector 并且想要展平结构,或者一个这样的 vector 的 std::vector。天真地,我现在会继续编写这种类型的函数。

template<class A> void flatten_transfer(std::vector<A>& target, const std::vector<custom_list_type>& source){
for(const auto& elem:source){
flat_transfer(target,elem);
}
}

template<class A> void flatten_transfer(std::vector<A>& target, const std::vector<std::vector<custom_list_type> >& source){
for(const auto& elem:source){
flat_transfer(target,elem);
}
}

等等等等。但我发现这不是很优雅,因为我需要每个深度级别的此功能的版本。我想有一种更优雅的方法可以使用一些模板魔术来解决这个问题,但我的知识还不足以想出一个真正更好的解决方案。

使用模板抽象出 vector 深度级别的“推荐”方法是什么,这样只需要编写一个 flatten_transfer 实例?

最佳答案

假设我正确地理解了这个问题,下面的函数模板在 C++17 及更高版本中可以很好地用于此目的。此函数实例化 target.push_back(elem) 当且仅当 AB 相同时。否则,这将进入下一个深度:

Live DEMO

template<
class A,
class B,
template <class...> class Container,
class... extras>
void flat_transfer(std::vector<A>& target, const Container<B, extras...>& source)
{
for(const auto& elem : source)
{
if constexpr(std::is_same<A, B>::value){
target.push_back(elem);
}
else{
flat_transfer(target, elem);
}
}
}

这是一个用法示例:

std::vector<int> v{1,2,3};
std::set<std::vector<std::deque<int>>, std::greater<>> vv{{{4,5}, {6,7}, {8,9}}, {{10,11,12}, {13,14}, {15}}};

flat_transfer(v, vv);

// prints "1 2 3 10 11 12 13 14 15 4 5 6 7 8 9"
for(const auto& i : v){
std::cout << i << " ";
}

关于C++ 递归模板分辨率 : flattening vectors of vectors elegantly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55705553/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com