off*_*ull 1 c++ c++20 std-ranges
下面的代码在 g++-11.3 下使用编译--std=c++20 -D_GLIBCXX_DEBUG并执行时,会产生有关迭代器的奇怪运行时错误。range我不太确定这意味着什么,但我怀疑它与返回时超出范围的向量有关test():range没有被移动或复制,而是无论管道运算符返回什么,都只保留对range.
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
auto common = range | std::views::common;
return std::unordered_set<r_type>(std::ranges::begin(common), std::ranges::end(common));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return range | std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
return 0;
}
/*
/opt/compiler-explorer/gcc-11.3.0/include/c++/11.3.0/debug/safe_iterator.h:195:
In function:
__gnu_debug::_Safe_iterator<_Iterator, _Sequence,
_Category>::_Safe_iterator(__gnu_debug::_Safe_iterator<_Iterator,
_Sequence, _Category>&&) [with _Iterator =
__gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int,
std::allocator<int> > >; _Sequence = std::__debug::vector<int>;
_Category = std::forward_iterator_tag]
Error: attempt to copy-construct an iterator from a singular iterator.
Objects involved in the operation:
iterator "this" @ 0x0x7ffea2b7a8c0 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
}
iterator "other" @ 0x0x7ffea2b7a820 {
type = __gnu_cxx::__normal_iterator<int*, std::__cxx1998::vector<int, std::allocator<int> > > (mutable iterator);
state = singular;
references sequence with type 'std::__debug::vector<int, std::allocator<int> >' @ 0x0x7ffea2b7a8b0
}
*/
Run Code Online (Sandbox Code Playgroud)
无论如何,有没有办法让这样的事情发挥作用?我基本上想转换/过滤/连接/等等......一个范围并返回它(返回整个事物的副本/移动,范围和任何修改都应用于它)。
首先,由于std::vector本身是common_range,transform_view也将是,所以这里common_range使用是多余的。views::common
其次也是更重要的是,range它是一个局部变量,因此一旦离开它就会被销毁test(),这使得test()return atransform_view持有一个悬空指针。
无论如何,有没有办法让这样的事情发挥作用?
感谢P2415,您可以直接返回 atransform_view应用于rvalue vector,这将构造一个owning_view将原始内容的所有权转移vector给自身的 an ,这将不再导致悬空。
#include <ranges>
#include <unordered_set>
#include <vector>
auto to_unordered_set(auto && range) {
using r_type = std::ranges::range_value_t<decltype(range)>;
return std::unordered_set<r_type>(
std::ranges::begin(range), std::ranges::end(range));
}
auto test() {
std::vector<int> range {1,2,3,4,5};
return std::move(range) |
std::ranges::views::transform([](auto x) { return x%2; });
}
int main() {
auto y = to_unordered_set(test());
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
167 次 |
| 最近记录: |