【发布时间】:2021-03-21 16:55:11
【问题描述】:
此代码有效并生成正确的输出(23,因为2 和3 是array_of_vectors 中两个std::vector<int>s 的大小:
#include <array>
#include <boost/range/adaptor/transformed.hpp>
#include <iostream>
#include <vector>
using boost::adaptors::transformed;
constexpr auto get_size = [](auto const& snip){ return snip.size(); };
int main() {
std::array<std::vector<int>,2> array_of_vectors = {
{std::vector<int>{1,1}, std::vector<int>{1,1,1}}
};
auto array_of_sizes = array_of_vectors | transformed(get_size);
for (auto i : array_of_sizes) {
std::cout << i;
}
}
另一方面,如果我尝试通过更改这个来强制通过boost::copy_range 强制array_of_sizes 确实是std::array<std::size_t, 2u>
auto array_of_sizes = array_of_vectors | transformed(get_size);
到这里
auto array_of_sizes = boost::copy_range<std::array<std::size_t, 2u>>(
array_of_vectors | transformed(get_size)
);
我收到以下错误,
$ g++ -std=c++17 deleteme.cpp && ./a.out
In file included from /usr/include/boost/range/iterator_range.hpp:13,
from /usr/include/boost/range/adaptor/transformed.hpp:16,
from deleteme.cpp:2:
/usr/include/boost/range/iterator_range_core.hpp: In instantiation of ‘SeqT boost::copy_range(const Range&) [with SeqT = std::array<long unsigned int, 2>; Range = boost::range_detail::transformed_range<<lambda(const auto:1&)
2> >]’:
deleteme.cpp:16:114: required from here
/usr/include/boost/range/iterator_range_core.hpp:842:20: error: no matching function for call to ‘std::array<long unsigned int, 2>::array(boost::range_detail::extract_const_iterator<boost::range_detail::transformed_range<<la
y<std::vector<int>, 2> >, true>::type, boost::range_detail::extract_const_iterator<boost::range_detail::transformed_range<<lambda(const auto:1&)>, std::array<std::vector<int>, 2> >, true>::type)’
842 | return SeqT( boost::begin( r ), boost::end( r ) );
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from deleteme.cpp:1:
/usr/include/c++/10.2.0/array:94:12: note: candidate: ‘std::array<long unsigned int, 2>::array()’
94 | struct array
| ^~~~~
/usr/include/c++/10.2.0/array:94:12: note: candidate expects 0 arguments, 2 provided
/usr/include/c++/10.2.0/array:94:12: note: candidate: ‘constexpr std::array<long unsigned int, 2>::array(const std::array<long unsigned int, 2>&)’
/usr/include/c++/10.2.0/array:94:12: note: candidate expects 1 argument, 2 provided
/usr/include/c++/10.2.0/array:94:12: note: candidate: ‘constexpr std::array<long unsigned int, 2>::array(std::array<long unsigned int, 2>&&)’
/usr/include/c++/10.2.0/array:94:12: note: candidate expects 1 argument, 2 provided
另一方面,令我惊讶的是(!),如果我强制 array_of_sizes 成为 std::vector<std::size_t>,例如
auto array_of_sizes = boost::copy_range<std::vector<std::size_t>>( // vector instead of array
array_of_vectors | transformed(get_size)
);
有效!看起来transformed 将std::array<T,N> 转换为可转换为std::vector<T> 的范围,就像它丢失了std::array 的编译时大小一样。
这个错误/行为是由什么引起的?
我只能认为由于std::array 的编译时已知大小而不是std::vector 的运行时大小,某些东西不起作用。可能transformed 无法处理?或者可能是copy_range 不能?
【问题讨论】:
-
boost::range::copy怎么样?你也试过了吗?问题是array_of_vectors的元素是std::vectors。尝试制作array_of_vectors的元素std::arrays。 -
嗯,它确实有效,但它也迫使我事先创建
array_of_size以便我可以将它作为第二个参数传递,而如果它是一个返回值会更有用,这样我可以在需要时直接将其传递给其他函数。但是,您的建议加强了我的理解,即我的解决方案不起作用,因为在编译时不知道transformed的输出大小(即使可以,因为输入数组的大小 is 在编译时知道)。 -
我的评论能回答你的问题吗?我可以把它变成实际的答案吗?
-
@NutCracker,你当然可以,我会 +1,但在接受之前我想知道 为什么
copy_range不起作用,如果有“输入-输出”解决方案,而不是“变异输入”解决方案。
标签: c++ arrays templates boost c++17