我想创建一个deep_flatten
函数模板,它会产生一个深度编辑range
的元素。join
例如,如果我们只考虑嵌套std::vector
的 s,我可以有:
template <typename T>
struct is_vector : public std::false_type { };
template <typename T, typename A>
struct is_vector<std::vector<T, A>> : public std::true_type { };
template <typename T>
auto deepFlatten(const std::vector<std::vector<T>>& vec) {
using namespace std::ranges;
if constexpr (is_vector<T>::value) {
auto range = vec | views::join;
return deepFlatten(std::vector(range.begin(), range.end()));
} else {
auto range = vec | views::join;
return std::vector(range.begin(), range.end());
}
}
这使我能够做到:
std::vector<std::vector<std::vector<int>>> nested_vectors = {
{{1, 2, 3}, {4, 5}, {6}},
{{7}, {8, 9}, {10, 11, 12}},
{{13}}
};
std::ranges::copy(
deep_flatten(nested_vectors),
std::ostream_iterator<int>(std::cout, " ")
);
正如预期的那样,它将以下文本打印到控制台中:
1 2 3 4 5 6 7 8 9 10 11 12 13
但是,我不太喜欢这个解决方案。它不仅效率低下(创建许多临时向量),而且它也仅适用于std::vector
s. 我想我可以使用更多的c++20魔法和使用std::ranges::range
概念:
namespace rng {
template <std::ranges::range Rng>
auto deep_flatten(Rng&& rng) {
using namespace std::ranges;
if constexpr (range<Rng>) {
return deep_flatten(rng | views::join);
} else {
return rng | views::join;
}
}
}
这在我看来很简单——我们有一个std::ranges::range
并且我们检查它的值类型。根据它是否是嵌套范围,我们递归或简单地返回join
ed 元素。
可悲的是,它不起作用。尝试运行后:
int main() {
std::set<std::vector<std::list<int>>> nested_ranges = {
{{1, 2, 3}, {4, 5}, {6}},
{{7}, {8, 9}, {10, 11, 12}},
{{13}}
};
std::ranges::copy(
rng::deep_flatten(nested_ranges),
std::ostream_iterator<int>(std::cout, " ")
);
}
我收到一条错误消息:
In instantiation of 'auto rng::deep_flatten(Rng&&) [with Rng = std::ranges::join_view<std::ranges::ref_view<std::set<std::vector<std::__cxx11::list<int> > > > >]': required from 'auto rng::deep_flatten(Rng&&) [with Rng = std::set<std::vector<std::__cxx11::list<int> > >&]' required from here error: use of 'auto rng::deep_flatten(Rng&&) [with Rng = std::ranges::join_view<std::ranges::ref_view<std::set<std::vector<std::__cxx11::list<int> > > > >]' before deduction of 'auto' 39 | return deep_flatten(rng | views::join); | ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
研究了类似的问题后,我无法真正理解为什么会出现错误。
我在用gcc version 10.1.0 (Rev3, Built by MSYS2 project)